2016-03-20 4 views
-1

Скажем, у меня есть набор из 50 переменных и 50 наблюдений.Случайный доступ к n наблюдениям

Возможно ли получить доступ к 100 случайным ячейкам и изменить их значения?

Было бы здорово, если бы мне не пришлось использовать SQL для этого.

+0

1. Да, 2. Я не знаю, в чем вопрос. Пожалуйста, расширьте то, что вы пытаетесь сделать. – Reeza

+0

@Reeza Я удалил второй вопрос, потому что концепция не имела смысла. Можете ли вы рассказать о первом? –

+0

Вам нужно объяснить, что вы хотите сделать более подробно, и то, что вы пробовали. Кроме того, у вас есть SAS/IML. – Reeza

ответ

1

Ваша частота дискретизации - 0,04 - 4% от числа записей будет отсутствовать. Я предполагаю, что у вас есть переменные, которые имеют одинаковый тип и могут быть перечислены в массиве. Тем не менее, есть способы обойти это. Другой вариант - перевернуть ваши данные в широкую структуру, используйте Proc SurveySelect, чтобы выбрать 100 случайных значений и установить отсутствие. В приведенном ниже коде используются только методы BASE SAS.

/*Generate sample data*/ 
data sample; 
array var(50) var1-var50; 
do i=1 to 50; 
    do j=1 to 50; 
     var(j)=rand('normal', 25, 4); 
     end; 
    output; 
end; 

drop i j; 
run; 

*randomly assign to missing; 
data sample_missing; 
    call streaminit(123); *ensure reproducible 100 records; 
    set sample; 
    array var(50) var1-var50; 
    rate=100/(50*50); *based on your question; 

    retain num_miss 0; 
    do i=1 to 50; 

    if rand('bernoulli', rate) = 1 and num_miss < 100 then do; 
     var(i)=.; 
     num_miss+1; 
    end; 

    end; 
run; 

/*Check the values and code*/ 
data check; 
set sample_missing end=eof; 
retain nmiss_cum; 
nmiss_row = nmiss(of var1--var50); 
nmiss_cum+nmiss_row; 

/*if you only want to see the total number missing for checks uncomment the next two lines*/ 
**if eof then output; 

* *keep nmiss_cum; 
run; 
+0

Я надеялся, что можно будет изменить ровно 100 значений (и без преобразования данных в одно измерение), но кажется, что ваш ответ лучше всего. Благодарю. –

+0

Мой код не преобразует размер и в моих выборках выполнил ровно 100 .... – Reeza

+0

Для этого семени, да. Кроме того, я думаю, вы хотели передать переменную 'rate' в' rand() ', если я правильно понимаю. –

1

Если вы хотите ровно 100 отсутствующих значений, метод прямой прямой перемотки будет представлять ваши данные как 2500 ячеек. Создайте список из 100 случайных чисел от 1 до 2500. Затем установите эти ячейки в пропасть. Что-то вроде ниже:

data sample; 
    array x(50); 
    do i=1 to 50; 
    do j=1 to 50; 
     x(j)=rand('normal', 25, 4); 
    end; 
    output; 
    end; 

    drop i j; 
run; 

**Generate list of 100 random numbers (there are doubtless better ways :); 
data cellno; 
    do cellno=1 to 2500; 
    ran=ranuni(3); 
    output; 
    end; 
run; 
proc sql outobs=100 noprint; 
    select cellno into :celllist separated by " " 
    from cellno 
    order by ran 
    ; 
run; 

%put &celllist; 

*Use that list to recode 100 cells to null; 
data want; 
    set sample; 
    array x(50); 
    do i=1 to 50; 
    if (_n_-1)*50+i IN (&celllist) then 
     call missing(x{i}); 
    end; 
    drop i; 
run; 
1

Возможно, проще всего применить к этой проблеме метод случайных выборок K/N. Единственное отличие состоит в том, что вместо того, чтобы просто выбирать по наблюдениям, вы выбираете над отдельными элементами в массиве переменных.

%let seed=12345; 
%let varlist=X1-X50 ; 
%let samplesize= 100 ; 

data want; 
    set have nobs=nobs ; 
    array x &varlist ; 
    retain _count &samplesize ; 
    retain _left ; 
    if _n_=1 then _left=dim(x)*nobs ; 
    do i=1 to dim(x); 
    if (_count/_left > ranuni(&seed)) then do; 
     x(i) = . ; 
     _count = _count - 1; 
    end; 
    _left = _left - 1; 
    end; 
    drop _left _count i ; 
run;