Преобразовать if затем построить в case_when во вложенных данных, используя purrr map2 - PullRequest
0 голосов
/ 02 мая 2018

Вот мои данные:

vec1 <- c("A", "B")
vec2 <- c("A", "B", "C")

df1 <- structure(list(A = c("X", "Y"), data = list(structure(list(B = c(4L, 9L)), .Names = "B", row.names = c(NA, -2L), class = c("tbl_df", "tbl", "data.frame")), structure(list(B = c(5L, 2L, 8L, 2L)), .Names = "B", row.names = c(NA, -4L), class = c("tbl_df", "tbl", "data.frame"))), C = list(c("A", "B"), c("A", "B", "C"))), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -2L), .Names = c("A", "data", "C"))

Вот мой код:

df2 <- df1 %>% mutate(data = map2(data, C, ~ if(identical(.y, vec1)) filter(.x, B < 5) else filter(.x, B > 4)))

Чтобы легко расширить число условий, я хочу преобразовать конструкцию if else из кода выше в конструкцию case_when. Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Зачем вам нужно case when?

Попробуйте:

m=df1%>%
  mutate(filt=map2(data,match(C,list(vec1,vec2)),
               ~filter_(.x,c("B<=4","B>4")[.y])))

   m
# A tibble: 2 x 4
  A     data             C         filt            
  <chr> <list>           <list>    <list>          
1 X     <tibble [2 x 1]> <chr [2]> <tibble [1 x 1]>
2 Y     <tibble [4 x 1]> <chr [3]> <tibble [2 x 1]>

Если вы хотите, чтобы он совпадал с вашим df2, просто замените столбец data:

df1%>%
      mutate(data=map2(data,match(C,list(vec1,vec2)),
                   ~filter_(.x,c("B<=4","B>4")[.y])))%>%
      identical(df2)
 [1] TRUE

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

   conditions=c("B>4","B<=4")
   ll=list(vec2,vec1)
   df1%>%
      mutate(data=map2(data,match(C,ll),
                   ~filter_(.x,conditions[.y])))%>%
      identical(df2)
     [1] TRUE
0 голосов
/ 02 мая 2018

К сожалению, в этом контексте я не знаю, можно ли использовать case_when. В документации говорится, что он возвращает вектор и проверяет, чтобы все элементы были одного типа (как того требуют векторы в R). Это в отличие от базы ifelse, например, которая приведет к характеру. Поскольку вы возвращаете список, а не вектор, и поэтому все элементы имеют разный тип, case_when не будет работать. Вам, вероятно, потребуется указать более длинную цепочку if else if, если у вас есть много разных vec со связанными действиями, которые вам нужно обработать.

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