Скажем, у меня есть набор из 50 переменных и 50 наблюдений.Случайный доступ к n наблюдениям
Возможно ли получить доступ к 100 случайным ячейкам и изменить их значения?
Было бы здорово, если бы мне не пришлось использовать SQL для этого.
Скажем, у меня есть набор из 50 переменных и 50 наблюдений.Случайный доступ к n наблюдениям
Возможно ли получить доступ к 100 случайным ячейкам и изменить их значения?
Было бы здорово, если бы мне не пришлось использовать SQL для этого.
Ваша частота дискретизации - 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;
Я надеялся, что можно будет изменить ровно 100 значений (и без преобразования данных в одно измерение), но кажется, что ваш ответ лучше всего. Благодарю. –
Мой код не преобразует размер и в моих выборках выполнил ровно 100 .... – Reeza
Для этого семени, да. Кроме того, я думаю, вы хотели передать переменную 'rate' в' rand() ', если я правильно понимаю. –
Если вы хотите ровно 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;
Возможно, проще всего применить к этой проблеме метод случайных выборок 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;
1. Да, 2. Я не знаю, в чем вопрос. Пожалуйста, расширьте то, что вы пытаетесь сделать. – Reeza
@Reeza Я удалил второй вопрос, потому что концепция не имела смысла. Можете ли вы рассказать о первом? –
Вам нужно объяснить, что вы хотите сделать более подробно, и то, что вы пробовали. Кроме того, у вас есть SAS/IML. – Reeza