#r #if-statement
Вопрос:
У меня возникли проблемы с выбором строк на основе условий убывающего приоритета. Я пытался найти решение, но просто не могу. Это кажется простой задачей, но я просто не могу в этом разобраться.
Это всего лишь общий пример того, что я хотел бы сделать.
structure(list(type = c(100815L, 100815L, 100815L, 100815L,
100815L, 100815L, 100815L), x = structure(c(1L,
1L, 1L, 2L, 1L, 2L, 2L), .Label = c("No", "Yes"), class = "factor"),
y = c(1.51098844290943, 2.31001922745969, 1.52639281812227,
0, 0, 0, 0), z = c(0, 0, 0, 25, 0, 50, 25)), row.names = c(NA,
-7L), class = c("tbl_df", "tbl", "data.frame"))
group <- group %>%
group_by(type) %>%
filter(sum(x == "Yes" amp;
y == min(y[x == "Yes"]) amp;
z == max(z[y == min(y[x == "Yes"])])) == 1)
Поэтому в основном я хочу отфильтровать из большой выборки группы, в которых есть ровно один такой случай. т. е. связей нет:
- Когда x = «Да» И
- учитывая, что x = «Да», выберите минимальный y из тех, у кого x = «Да», И
- из этой последней наименьшей группы выберите z, которая имеет наибольшее значение.
- учитывая, что x = «Да», выберите минимальный y из тех, у кого x = «Да», И
В принципе, также возможно, что такого конечного значения не существует.
Это упрощенный пример проблемы, с которой я постоянно сталкиваюсь. У меня есть больший набор данных, в котором мне нужно присваивать значения ячейкам на основе нескольких условий, имеющих приоритет по убыванию. Я хочу иметь возможность последовательно складывать условия.
Обновить
structure(list(type = c(7345L, 7345L, 7345L, 7345L, 7345L,
7345L, 7345L, 7345L, 7345L, 7345L, 7345L, 7345L, 7345L, 7345L,
7345L, 7345L, 7345L, 7345L, 7345L, 7345L, 7345L, 7345L, 7345L
), x= structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L
), .Label = c("No", "Yes"), class = "factor"), y = c(1.66703903751618,
0, 0.899002060282742, 1.77844476717205, 0.858205995526113, 1.77844476717205,
0.894654725714929, 2.28497216539696, 0, 0.899002060282742, 2.28497216539696,
2.85895315127563, 2.85895315127563, 0, 2.85895315127563, 0.858205995526113,
0.894654725714929, 1.66703903751618, 1.66703903751618, 0, 0,
1.66703903751618, 0.894654725714929), z = c(6.67,
0, 3.33, 6.67, 3.33, 6.67, 2, 6.67, 3.33, 3.33, 2, 3.33, 3.33,
2, 3.33, 6.67, 6.67, 6.67, 2, 6.67, 3.33, 6.67, 2)), row.names = c(NA,
-23L), class = c("tbl_df", "tbl", "data.frame"))
# And the code that I attempted:
test <- test %>%
group_by(type) %>%
arrange(type) %>%
filter(sum(y == min(y) amp; x == "Yes") == 1) %>%
ungroup()
Группа здесь должна быть отфильтрована, насколько я понимаю, но просто не делает этого. Есть два «Да», но у другого меньше y, и должно быть только один случай, когда происходит правило, но фильтр его не выбирает.
Это была всего лишь ограниченная версия с двумя условиями. В основном я пытаюсь назначить «Да» только одному крестику. Если их несколько, связь разрывается на y. Если галстук все еще есть, галстук разрывается z. И так далее, я надеюсь. Я просто не могу заставить это работать.
Ответ №1:
Я думаю, что это то, что вы ищете:
df %>% group_by(type) %>% filter(x == "Yes",y == min(y),z == max(z))
# # A tibble: 1 × 4
# # Groups: type [1]
# type x y z
# <int> <fct> <dbl> <dbl>
# 1 100815 Yes 0 50
Комментарии:
1. Я думаю , что это использование глобальных значений для
min(y)
иmax(z)
, а не значений внутри подмножеств. Вы получаете те же ответы с образцами данных, но если ни в одном случае не былоx=="Yes"
,y == 0
, иz == 50
, вы вообще не получаете случаев. Разделениеfilter
вызова на три отдельных вызова, по-видимому, делает это.2. В любом случае я получаю один и тот же ответ, но я не проверял его на альтернативном наборе данных.
3. Извините за задержанный ответ, я проверял, работает ли он во всех случаях. Ваше решение помогает с этой конкретной группой, но не со всеми, и я не понимаю, почему. Я обновлю пост, чтобы показать, где это правило выбора не сработало.
4. Одновременное применение фильтров (запятая действует как эквивалент И логики) приводит к потенциальному сбою: если
min(y)
значение имеет значение forx == "No"
, логика ломается, и не остается никакого правила. Изменение кода на три последовательныхfilter
вызова должно привести к правильному поведению.5. @user2554330 разделение
filter
работало для разделения значения, но побочный эффект заключается в том, что оно отделяет строку от группы. Я пытаюсь собрать группы, в которых выполняется условие, а затем на следующем шаге измените x на «Нет» для строк, для которых условие не выполняется. Я обновлю вопрос, чтобы показать вам, что я пытаюсь сделать после этого шага.