2016-07-11 5 views
0

グループの頻度分布に基づいて空白サイズのIDを割り当てたいと思います。 ID 8の場合配信に基づく不足している変数値の割り当てSAS

Group Small Medium Large 
A  0.31 0.25 0.44 
B  0.43 0.22 0.35 
C  0.10 0.13 0.78 
D  0.29 0.27 0.44 

、我々はそれが持っていることを知っている:

ID Group Size 
1 A  Large 
2 B  Small 
3 C  Small 
5 D  Medium 
6 C  Large 
7 B  Medium 
8 B  - 

データセットBは、グループ間の大きさの頻度分布を示しています

データセットAは、私のデータのスナップショットが含まれています43%の確率は「小さい」、22%の確率は「中」、35%の確率は大きい。これはグループBのサイズ分布であるからです。

データセットBのグループ分布に基づいてID 8(および他のブランクID)のサイズを割り当てるにはどうすればよいですか?私はSAS 9.4を使用しています。マクロ、SQL、何でも歓迎です!

答えて

0

tableの分布がこれに最適です。ここでの最後のデータはそれを示しています。その前に、データを無作為に作成して頻度テーブルを決定するように設定しました。その場合は、それをスキップすることができます。

その他の使用例(および機能の詳細については、この例は、simulating multinomial dataのRick Wicklinのブログを参照してください。

*Setting this up to help generate random data; 
proc format; 
    value sizef 
    low - 1.3 = 'Small' 
    1.3 <-<2.3 = 'Medium' 
    2.3 - high = 'Large' 
; 
quit; 

*Generating random data; 
data have; 
    call streaminit(7); 
    do id = 1 to 1e5; 
    group = byte(65+rand('Uniform')*4); *A = 65, B = 66, etc.; 
    size = put((rank(group)-66)*0.5 + rand('Uniform')*3,sizef.); *Intentionally making size somewhat linked to group to allow for differences in the frequency; 
    if rand('Uniform') < 0.05 then call missing(size); *A separate call to set missingness; 
    output; 
    end; 
run; 

proc sort data=have; 
    by group; 
run; 

title "Initial frequency of size by group"; 
proc freq data=have; 
    by group; 
    tables size/list out=freq_size; 
run; 
title; 

*Transpose to one row per group, needed for table distribution; 
proc transpose data=freq_size out=table_size prefix=pct_; 
    var percent; 
    id size; 
    by group; 
run; 


data want; 
    merge have table_size; 
    by group; 
    array pcts pct_:; *convenience array; 

    if first.group then do _i = 1 to dim(pcts); *must divide by 100 but only once!; 
    pcts[_i] = pcts[_i]/100; 
    end; 

    if missing(size) then do; 
    size_new = rand('table',of pcts[*]); *table uses the pcts[] array to tell SAS the table of probabilities; 
    size = scan(vname(pcts[size_new]),2,'_'); 
    end; 
run; 



title "Final frequency of size by group"; 
proc freq data=want; 
    by group; 
    tables size/list; 
run; 
title; 
+0

これは機能しました!ご協力いただきありがとうございます。 – user3910919

0
また、ランダムな値といくつかのif-elseロジックでこれを行うことができ

proc sql; 
    create table temp_assigned as select 
     a.*, rand("Uniform") as random_roll, /*generate a random number from 0 to 1*/ 
     case when missing(size) then 
      case when calculated random_roll < small then small 
       when calculated random_roll < sum(small, medium) then medium 
       when calculated random_roll < sum(small, medium, large) then large 
      end end as value_selected, /*pick the value of the size associated with that value in each group*/ 
     coalesce(case when calculated value_selected = small then "Small" 
        when calculated value_selected = medium then "Medium" 
        when calculated value_selected = large then "Large" end, size) as group_assigned /*pick the value associated with that size*/ 
     from temp as a 
     left join freqs as b 
     on a.group = b.group; 
quit; 

は明らかにあなたがvalue_selected変数を作成せずにこれを行うことができますが、私は実証の目的のためにそれを示すと思っただろう助けてください。

関連する問題