#r #loops #filter #outliers
#r #циклы #Фильтр #выбросы
Вопрос:
У меня есть несколько условий и несколько типов измерений в моих данных.
Я хочу, чтобы R давал мне значение выбросов для каждой пары условий и типа измерения отдельно.
Итак, например, допустим, у меня есть 3 условия (1-3) и 3 типа мер (A-C) для нескольких участников со значением x для каждой строки. Я хочу иметь выбросы значений x для condition1amp; measureA, condition2 amp; MeasureB и т. Д.
(мера и условие являются нечисловыми)
Я попытался создать цикл
for(d in unique(data$measure)){
for(c in unique(data$condition)){
data %>%
filter(measure == d, condition ==c) %>%
o <- outlier(data$value) %>%
print(o)
}
}
Идея в том, что R будет проходить через каждое условие и измерять в цикле, и каждый раз выбирать значения, которые соответствуют им, и вычислять выбросы.
Когда я запускаю весь код, я получаю это сообщение об ошибке
Error in print.default(., o) : invalid printing digits -2147483648
In addition: Warning message:
In print.default(., o) : NAs introduced by coercion to integer range
(Если я запускаю его без цикла, например, путем поиска выбросов для определенного условия, он также не может найти функцию канала после первой строки.)
Есть идеи о том, как правильно это закодировать?
Комментарии:
1. Если вы уже используете
dplyr
, вы намеренно избегаете его встроенной (и более эффективной)group_by
функциональности?
Ответ №1:
Вы уже используете dplyr
, поэтому я предлагаю вам использовать group_by
, поскольку это (для меня) более естественный способ работы с данными.
Кроме того, эта часть имеет неправильный синтаксис:
data %>%
filter(measure == d, condition ==c) %>%
o <- outlier(data$value) %>%
print(o)
Почему?
-
Они
filter(...) %>%
должны быть подключены к чему-то, что принимает фрейм, но … вы отправляете выходные данные изfilter
в назначениеo <- outlier(...)
(а затем вprint(o)
, что на самом деле означаетprint(., o)
, где.
находится вывод из предыдущей команды. -
Кроме того, since
o
еще не определен при первом запуске… вы должны получить сообщение обobject 'o' not found
ошибке. Вы не получите его при последующих проходах в цикле, поскольку он существует… но если это так, то это выбросы от предыдущей итерации в циклах. Конечно, не то, что вы должны использовать.
Прямое исправление этого кода может быть:
for (...) {
for (...) {
o <- data %>%
filter(measure == d, condition ==c) %>%
do({ data.frame(outliers = outlier(.$value)) })
print(o)
}
}
где o
будет data.frame
(ну, tbl_df
tibble) с тремя столбцами: measure
, condition
, и outliers
. В do
этом случае требуется использование, потому что большинство функций, не связанных с tidyverse, игнорируют group_by
группировки, поэтому мы используем do
, чтобы обойти эту проблему.
Возможно, это, однако, для замены обоих циклов в одну команду:
data %>%
group_by(measure, condition) %>%
summarize(outliers = outlier(value)) %>%
ungroup()
Я предполагаю, что вам нужны все значения выбросов для каждой уникальной комбинации measure
и condition
, и что outlier(.)
функция возвращает вектор (некоторой длины> = 1). Если выбросы не обнаружены, measure
condition
пара / не будет включена … если это фактор, то используйте что-то вроде
data %>%
group_by(measure, condition) %>%
summarize(outliers = list(outlier(value))) %>%
tidyr::unnest(outliers, keep_empty = TRUE) %>%
ungroup()