Имею данные, аналогичные df3. Чтобы воспроизвести данные, запустите следующее:
vec1 <- c("A", "B")
vec2 <- c("A", "B", "C")
df1 <- tibble::tribble(
~A, ~B,
"X", 4L,
"X", 9L,
"Y", 5L,
"Y", 2L,
"Y", 8L,
"Y", 2L) %>%
group_by(A) %>%
nest()
df2 <- tibble::tribble(
~A, ~C,
"X", vec1,
"Y", vec2)
df3 <- df1 %>% left_join(df2, by = "A")
Мне нужно отфильтровать вложенные данные, используя что-то вроде этого:
df4 <- df3 %>% filter(when C==vec1, B (part of nested data now) < 5
when C==vec2, B (part of nested data now) >4)
или может быть так:
df4 <- df3 %>% map(.$data, ~filter((identicle(.$C, vec1) & B < 5) |
identical(.$C, vec2) & B >4))
У меня просто df3, и я хочу df4. Как мне выполнить указанную выше фильтрацию с помощью purrr, чтобы получить следующий желаемый результат в формате df4.
df11 <- tibble::tribble(
~A, ~B,
"X", 4L,
"Y", 5L,
"Y", 8L) %>%
group_by(A) %>%
nest()
df4 <- df11 %>% left_join(df2, by = "A")
Я хочу отфильтровать B, который находится внутри вложенных фреймов данных с именем переменной «данные», автоматически созданным вложением. Я обновил вопрос, чтобы отразить желаемый результат.
Это не очень эффективно, но вы можете перечислить match
: например, match(df3$C, list(vec1,vec2))
, который даст вам флаг для решения, что делать дальше.
Можете ли вы предложить это в виде df4 <- ..... df3. Было бы очень полезно!
Вот один из вариантов использования map2
и identical
для проверки состояния:
df3 %>%
mutate(
data = map2(
data, C, ~ if (identical(.y, vec1)) filter(.x, B < 5) else filter(.x, B > 4)
)
) %>%
identical(df4)
# [1] TRUE
Это сработало. Вы можете помочь мне сделать это с помощью case_when?
Я не уверен, что вы можете использовать case_when
в этом контексте, поскольку вы хотите вернуть список, а case_when
требует векторного вывода. Следовательно, if
и else
Вот другой подход, который использует unnest
для непосредственной работы со значениями B
, впоследствии заменяя исходные векторы.
library(tidyverse)
vec1 <- c("A", "B")
vec2 <- c("A", "B", "C")
df3 <- 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"))
veclist <- list(vec1, vec2)
df3 %>%
mutate(vec = match(C, veclist)) %>%
unnest(data) %>%
filter(vec == 1 & B < 5 | vec == 2 & B > 4) %>%
nest(B) %>%
mutate(C = map(vec, ~ veclist[[.]])) %>%
as.data.frame()
#> A vec data C
#> 1 X 1 4 A, B
#> 2 Y 2 5, 8 A, B, C
Создано 01.05.2018 пользователем пакет REPEX (v0.2.0).
Нет необходимости в операторах if-else:
mine=df3%>%
mutate(data=map2(data,match(C,list(vec1,vec2)),
~filter_(.x,c("B<=4","B>4")[.y])))
identical(mine,df4)
[1] TRUE
Я не слежу за тем, как фильтруется
B
. Еслиdf3$data
состоит из вложенных столбцовB
, как вы проверяете, например,B < 5
? Если значениеany()
вB
равно< 5
? Если бы вы могли показать пример ожидаемого результатаdf4
, это было бы полезно.