Фильтрация с условиями приоритета по убыванию

#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, которая имеет наибольшее значение.

В принципе, также возможно, что такого конечного значения не существует.

Это упрощенный пример проблемы, с которой я постоянно сталкиваюсь. У меня есть больший набор данных, в котором мне нужно присваивать значения ячейкам на основе нескольких условий, имеющих приоритет по убыванию. Я хочу иметь возможность последовательно складывать условия.

Обновить

 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) значение имеет значение for x == "No" , логика ломается, и не остается никакого правила. Изменение кода на три последовательных filter вызова должно привести к правильному поведению.

5. @user2554330 разделение filter работало для разделения значения, но побочный эффект заключается в том, что оно отделяет строку от группы. Я пытаюсь собрать группы, в которых выполняется условие, а затем на следующем шаге измените x на «Нет» для строк, для которых условие не выполняется. Я обновлю вопрос, чтобы показать вам, что я пытаюсь сделать после этого шага.