В моих данных есть несколько условий и несколько типов измерений.
Я хочу, чтобы R давал мне значение выброса для каждой пары условий и типа измерения отдельно.
Так, например, предположим, что у меня есть 3 условия (1-3) и 3 типа мер (A-C) для нескольких участников со значением x для каждой строки. Я хочу получить выброс значений x для condition1 и measureA, condition2 и 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
Luise H 27 Сен 2020 в 00:13

1 ответ

Лучший ответ

Вы уже используете dplyr, поэтому я предлагаю вам использовать group_by, поскольку это (для меня) более естественный способ работы с данными.

Также в этой части неверный синтаксис:

    data %>%
      filter(measure == d, condition ==c) %>%
      o <- outlier(data$value) %>%
      print(o)

Зачем?

  1. filter(...) %>% должен быть связан с чем-то , которое принимает фрейм, но ... вы отправляете вывод из filter в назначение { {X2}} (а затем в print(o), что на самом деле означает print(., o), где . - результат предыдущей команды.

  2. Кроме того, поскольку 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()
0
r2evans 26 Сен 2020 в 21:37