2017-09-15 13 views
2

내 데이터가 세로입니다.세로 데이터에서 대체 할 수없는 랜덤 샘플링

VISIT ID VAR1 
1  001 ... 
1  002 ... 
1  003 ... 
1  004 ... 
... 
2  001 ... 
2  002 ... 
2  003 ... 
2  004 ... 

최종 목표는 테스트를 실행하기 위해 방문당 10 %를 선택하는 것입니다. 나는 proc SURVEYSELECT를 사용하여 SRS를 대체하지 않고 "VISIT"를 지층으로 사용하려고했습니다. 그러나 최종 샘플에는 중복 된 ID가 있습니다. 예를 들어, ID = 001은 VISIT = 1 W VISIT = 2 둘 다에서 선택 될 수 있습니다.

SURVEYSELECT 또는 다른 절차를 사용하는 방법이 있습니까? (R도 좋습니다)? 고마워.

+0

그래서 각 방문에서 10 %를 가져 가고 싶지만 최종 데이터 세트의 모든 ID는 고유해야합니다. – useR

+0

예. 니가 말했듯이. –

+0

방문으로 ID가 고유 한 경우 ave :'dat $ picked <- ave (is.numeric (dat $ VISIT), dat $ VISIT, sample (c (TRUE, FALSE), length probs = c (.1, .9), replac = TRUE))'. – lmo

답변

0

이것은 상당히 독창적 인 데이터 스텝 프로그래밍에서 가능합니다. 아래 코드는 이전에 샘플링되지 않은 ID 만 샘플링하여 각 방문에서 차례로 샘플링하는 검색 방식을 사용합니다. 방문에 대한 ID의 90 % 이상이 이미 샘플링 된 경우 10 % 미만이 출력됩니다. 극단적 인 경우 방문에 대한 모든 ID가 이미 샘플링 된 경우 방문에 대한 행이 출력되지 않습니다.

/*Create some test data*/ 
data test_data; 
    call streaminit(1); 
    do visit = 1 to 1000; 
    do id = 1 to ceil(rand('uniform')*1000); 
     output; 
    end; 
    end; 
run; 


data sample; 
    /*Create a hash object to keep track of unique IDs not sampled yet*/ 
    if 0 then set test_data; 
    call streaminit(0); 
    if _n_ = 1 then do; 
    declare hash h(); 
    rc = h.definekey('id'); 
    rc = h.definedata('available'); 
    rc = h.definedone(); 
    end; 
    /*Find out how many not-previously-sampled ids there are for the current visit*/ 
    do ids_per_visit = 1 by 1 until(last.visit); 
    set test_data; 
    by visit; 
    if h.find() ne 0 then do; 
     available = 1; 
     rc = h.add(); 
    end; 
    available_per_visit = sum(available_per_visit,available); 
    end; 
    /*Read through the current visit again, randomly sampling from the not-yet-sampled ids*/ 
    samprate = 0.1; 
    number_to_sample = round(available_per_visit * samprate,1); 
    do _n_ = 1 to ids_per_visit; 
    set test_data; 
    if available_per_visit > 0 then do; 
     rc = h.find(); 
     if available = 1 then do; 
     if rand('uniform') < number_to_sample/available_per_visit then do; 
      available = 0; 
      rc = h.replace(); 
      samples_per_visit = sum(samples_per_visit,1); 
      output; 
      number_to_sample = number_to_sample - 1; 
     end; 
     available_per_visit = available_per_visit - 1; 
     end; 
    end; 
    end; 
run; 

/*Check that there are no duplicate IDs*/ 
proc sort data = sample out = sample_dedup nodupkey; 
by id; 
run;