Пример использования начальных и конечных значений в цикле в R - PullRequest
1 голос
/ 01 ноября 2019

Я пытаюсь выбрать диапазон значений в рамках большего цикла в R. По мере продвижения цикла к каждой строке j я хочу выбрать число между значением, указанным в столбце start изначение, указанное в столбце end, помещающее это значение в столбец sampled для этой строки.

Результаты должны выглядеть примерно так:

ID  start  end  sampled
a   25     67   44
b   36     97   67
c   23     85   77
d   15     67   52
e   21     52   41
f   43     72   66
g   39     55   49
h   27     62   35
i   11     99   17
j   21     89   66
k   28     65   48
l   44     58   48
m   16     77   22
n   25     88   65

Я начал использовать mapply, который сэмплирует весь df, но затем я пытаюсь поместить все 15 сэмплированных значений водна строка.

df[j,4] <- mapply(function(x, y) sample(seq(x, y), 1), df$start, df$end)

Я подумал, что, возможно, что-то, использующее seq, может работать, но это приводит к ошибкам, говорящим, что from должно иметь длину 1.

df[j,4] <- sample(seq(df$start, df$end),1,replace=TRUE)

Структура внешнего цикла довольно сложна, поэтому я не включил ее здесь, но часть кода df[j,4] необходима, поскольку она является частью большего цикла. Существуют ситуации, когда строки должны быть пересчитаны на основе дополнительных зависимостей в фактическом наборе данных. Например, значение выборки a может быть больше b. Остальная часть кода обновляет столбец выборки, проверяет наличие зависимостей и повторно запускает образец, если зависимости не встречаются. Если мне удастся заставить этот раздел сэмплирования работать, я смогу подключить его без особых проблем (надеюсь).

Вот пример набора данных.

structure(list(ID = c("a", "b", "c", "d", "e", "f", "g", "h", 
"i", "j", "k", "l", "m", "n"), start = c(25, 36, 23, 15, 21, 
43, 39, 27, 11, 21, 28, 44, 16, 25), end = c(67, 97, 85, 67, 
52, 72, 55, 62, 99, 89, 65, 58, 77, 88), sampled = c(NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -14L), spec = structure(list(
    cols = list(ID = structure(list(), class = c("collector_character", 
    "collector")), start = structure(list(), class = c("collector_double", 
    "collector")), end = structure(list(), class = c("collector_double", 
    "collector")), sampled = structure(list(), class = c("collector_logical", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), skip = 1), class = "col_spec"))```

Ответы [ 3 ]

1 голос
/ 01 ноября 2019

Во-первых, поместите данные в формат, который проще использовать с dput(df):

df <- structure(list(ID = structure(1:14, .Label = c("a", "b", "c", 
    "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"), class = "factor"), 
    start = c(25L, 36L, 23L, 15L, 21L, 43L, 39L, 27L, 11L, 21L, 
    28L, 44L, 16L, 25L), end = c(67L, 97L, 85L, 67L, 52L, 72L, 
    55L, 62L, 99L, 89L, 65L, 58L, 77L, 88L), sampled = c(44L, 
    67L, 77L, 52L, 41L, 66L, 49L, 35L, 17L, 66L, 48L, 48L, 22L, 
    65L)), class = "data.frame", row.names = c(NA, -14L))

Вы были очень близки с mapply(), но сделали его сложнее, чем нужно:

df$sampled <- mapply(function(x, y) sample(seq(x, y), 1), df$start, df$end)
df
#    ID start end sampled
# 1   a    25  67      67
# 2   b    36  97      86
# 3   c    23  85      54
# 4   d    15  67      36
# 5   e    21  52      37
# 6   f    43  72      60
# 7   g    39  55      44
# 8   h    27  62      37
# 9   i    11  99      86
# 10  j    21  89      52
# 11  k    28  65      65
# 12  l    44  58      51
# 13  m    16  77      62
# 14  n    25  88      31
0 голосов
/ 02 ноября 2019

Разобрался. df[j,4] <- mapply(function(x, y) sample(seq(x, y), 1), df[j,"start"], df[j,"end"])

Мне просто нужно было точно указать, в какую строку выборочных значений я хотел бы ввести df[j,4]. Задание строки j для столбцов start и end сделало свое дело.

0 голосов
/ 01 ноября 2019

Возможно, вам не нужно проходить через. Если вам нужно что-то среднее между началом и концом, это почти эквивалентно выборке между 0-1 и умножению на диапазон.

df %>% mutate(sampled = start + round((end-start)*runif(nrow(.))))

Что касается обновления, зависимости, которые вы упомянули в своем комментарии: звучит немного сложно. Быстрое размышление: может быть быстрее пробовать много раз и выбрать тот, который соответствует вашим критериям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...