全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 SAS专版
4864 5
2014-12-15
看到一个帖子,是有关做simulation的。我对其中一段随机生成一个品牌的名字的这段code很感兴趣。

%let SEED = 2;
%let N_BEERS = 50;
%let ranChar  = byte(rank('A')+26*ranuni(&SEED));
%let ranDigit = byte(rank('0')+10*ranuni(&SEED));
data allBeers;
  do beer_id = 1 to &N_BEERS;
    beer_name = &ranChar. || &ranChar. || &ranChar.
             || &ranDigit.|| &ranDigit.|| &ranDigit.
    ;
    output;
  end;
run;


其中定义了ranchar和randigit这两个宏变量,然后在data步中使用它们。

但是这样的问题也有一个弊端,就是前三位一定是字母,而后三位一定是数字,因为这是由宏变量定义的。所以,如果我想要生成一个更随机的名字,连我自己也不知道第一位是数字还是字母,这时我觉得可以直接定义前两个宏变量分别为 ran1 和ran2,然后再生成一个随机变量ran3,使它取值为1或者2,这样在data步中调用&&ran&ran3.但是我始终不得其法。


%let ran1  = byte(rank('A')+26*ranuni(&SEED));
%let ran2 = byte(rank('0')+10*ranuni(&SEED));

data _null_;
b1 = ifn((ranuni(&SEED) > 0.5 ), 1, 2) ;
b2 = ifn((ranuni(&SEED) > 0.5 ), 1, 2) ;
b3 = ifn((ranuni(&SEED) > 0.5 ), 1, 2) ;
b4 = ifn((ranuni(&SEED) > 0.5 ), 1, 2) ;
b5 = ifn((ranuni(&SEED) > 0.5 ), 1, 2) ;
b6 = ifn((ranuni(&SEED) > 0.5 ), 1, 2) ;
call symputx('b1', b1);
call symputx('b2', b2);
call symputx('b3', b3);
call symputx('b4', b4);
call symputx('b5', b5);
call symputx('b6', b6);
put b1 b2 b3 b4 b5 b6;
run;


data allBeers;
  do beer_id = 1 to &N_BEERS;
    beer_name = &&ran&b1. || &&ran&b2. || &&ran&b3.|| &&ran&b4.|| &&ran&b5.||&&ran&b6.
    ;
    output;
  end;
run;

我想到的是这样一种方法,虽然这样可以一定程度上得到更随机的数字字母的组合,但是问题是从第一个到最后一个数据的所有类型都是一样的,也就是说,所有数据(这里定义50个)他们第一位都是数字(字母),第二个都是字母(或数字),想问问版上的大牛,有没有更随机的方法,比如第一个名字是PIT98T (字母|字母|字母|数据|数据|字母),第二个是(字母|数字|字母||数字|数字|数字),反正更加随机没有规律可循的。

谢谢大家了。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

全部回复
2014-12-15 09:56:46
%macro test;

%let SEED = 2;
%let N_BEERS = 50;
%let ranChar  = byte(rank('A')+26*ranuni(&SEED));
%let ranDigit = byte(rank('0')+10*ranuni(&SEED));
data allBeers;
  do beer_id = 1 to &N_BEERS;
    beer_name = %do i=1 %to 5; ifc((ranuni(&SEED) > 0.5 ), &ranChar., &ranDigit.) || %end;
                                ifc((ranuni(&SEED) > 0.5 ), &ranChar., &ranDigit.);
        output;
  end;
run;
%mend;

%test
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2014-12-15 12:50:04
jl60156 发表于 2014-12-15 09:56
%macro test;

%let SEED = 2;
十分感谢您的解答,
现在用了ifc这个function的话,可以在ranchar和randigit随机挑选一个,但是万一如果我把小写字母也引进来,也就是整个字符串是一个case sensitive的,

%let ran1  = byte(rank('A')+26*ranuni(&SEED));
%let ran2= byte(rank('0')+10*ranuni(&SEED));
%let ran3  = byte(rank('a')+26*ranuni(&SEED));

在这种情况下,应该怎么处理呢?
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2014-12-16 00:05:15
jl60156 发表于 2014-12-15 09:56
%macro test;

%let SEED = 2;
Question: There are 26 alphabets and 10 digits. Not clear why there is an equal chance (50 vs. 50) to generate char or number here.
I would explicitly list the string here rather than use byte/rank function. The reason is, easy-to-read may be the utmost important to maintain a program.
JingJu
复制代码
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2014-12-16 10:38:55
tangliang0905 发表于 2014-12-15 12:50
十分感谢您的解答,
现在用了ifc这个function的话,可以在ranchar和randigit随机挑选一个,但是万一如果 ...
if you want to take lowcase, upcase and digital with  probability 1/3 for each, you could use this

%macro test;
%let SEED = 2;
%let N_BEERS = 50;
%let ran1  = byte(rank('A')+26*ranuni(&SEED));
%let ran2= byte(rank('0')+10*ranuni(&SEED));
%let ran3  = byte(rank('a')+26*ranuni(&SEED));
%let seed2=12345;
data allBeers;
  length beer_name $6;
  %do beer_id = 1 %to &N_BEERS;
                  %do i=1 %to 6;
                %let b=0;
                %syscall ranuni(seed2,b);
                %let j=%sysevalf(%sysevalf(&b*3+1),floor);       
                    beer_name =&&ran&j.||beer_name;
             %end;
                beer_id=&beer_id;
        output;
        beer_name='';
  %end;
run;
%mend;

%test
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2014-12-16 23:30:07
jl60156 发表于 2014-12-16 10:38
if you want to take lowcase, upcase and digital with  probability 1/3 for each, you could use this ...
Yes, it can be applied for more general situation.
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群