Используйте функцию for-loop и if для создания нового вектора?

#r #for-loop #if-statement #vector

Вопрос:

Я хочу выполнить следующую операцию с кодом: я хочу получить выборку n = 30 из заданного нормального распределения и вычислить среднее значение для каждой выборки. (до этого шага моя функция работает без каких-либо проблем). После этого я хочу создать новый вектор с да или нет , в зависимости от того, находится ли среднее значение в определенном диапазоне или нет. К сожалению, код не выполняет этот шаг. Я всегда получаю вектор с 13 элементами,но их должно быть 500. В чем проблема? В чем моя ошибка?

 o = 13 u = 7 d = c() for (i in 1:500){  i = rnorm(30,mean = 10,sd = 6.04)  i = mean(i)  if (i lt;= o amp; i gt;=u) {  d[i]=("Yes")  } else {  d[i]=("No")  } }  

Ответ №1:

Вам следует избегать изменения значения вашего итератора ( i ) в вашем цикле. В вашем случае ваше i значение становится нецелым значением. Когда вы пытаетесь проиндексировать свой d вектор, он принимает целочисленную часть i .

Подумайте, что происходит, когда у меня есть вектор

 x lt;- 1:4  

и я беру pi его индекс.

 x[pi] # [1] 3  

Ваш код должен выглядеть примерно так:

 o = 13 u = 7  d = c()  for (i in 1:500){  sample_i = rnorm(30, mean = 10, sd = 6.04)  mean_i = mean(sample_i)  if (mean_i lt;= o amp; mean_i gt;=u) {  d[i]=("Yes")  } else {  d[i]=("No")  } }  

Если вы хотите немного улучшить свой код, вот несколько предложений:

Во-первых, избегайте «роста» ваших результатов. Это влияет на производительность. Лучше решить, какой длины должен быть ваш результат ( d ), и для начала установить его на эту длину.

Далее, постарайтесь не жестко кодировать количество итераций в вашем цикле. Ознакомьтесь с seq_along seq_len ними и используйте их для подсчета итераций для вас.

 o = 13 u = 7  d = numeric(500) # I made a change here  for (i in seq_along(d)){ # And I made a change here  sample_i = rnorm(30, mean = 10, sd = 6.04)  mean_i = mean(sample_i)  if (mean_i lt;= o amp; mean_i gt;=u) {  d[i]=("Yes")  } else {  d[i]=("No")  } }  

Комментарии:

1. Большое вам спасибо за подробный ответ. Это очень помогает !

Ответ №2:

Переназначение » я » кажется мне плохой идеей.

Вы уверены, что хотите сделать это в цикле for? Если нет, векторизованное решение с пересечением (tidyverse — хорошие объяснения на varianceexplained.org ) должно сработать довольно хорошо, я думаю?

 o = 13 u = 7  crossing(trial = 1:500,  rounds = 1:30)%gt;%  mutate(num = rnorm(n(), mean = 10, sd = 6.04))%gt;%  group_by(trial)%gt;%  summarise(mean = mean(num))%gt;%  mutate(d = case_when(mean lt;= o amp; mean gt;= u ~ "Yes",  TRUE ~ "No"))%gt;%  count(d)   

Комментарии:

1. Спасибо за ваш ответ. Я посмотрю на эту возможность и попытаюсь ее понять.