在带有 map() 的嵌套数据框中使用 filter()(和其他 dplyr 函数)
Use filter() (and other dplyr functions) inside nested data frames with map()
我正在尝试使用 purrr
包的 map()
将 filter()
函数应用于存储在嵌套数据框中的数据。
“为什么不先过滤,然后嵌套? - 你可能会问。
这会奏效(我将使用这样的过程展示我想要的结果),但我正在寻找使用 purrr
来实现它的方法。
我只想有一个数据框,有两个列表列,都是嵌套数据框 - 一个完整的和一个过滤的。
我现在可以通过执行 nest()
两次来实现它:一次针对所有数据,第二次针对过滤后的数据:
library(tidyverse)
df <- tibble(
a = sample(x = rep(c('x','y'),5), size = 10),
b = sample(c(1:10)),
c = sample(c(91:100))
)
df_full_nested <- df %>%
group_by(a) %>%
nest(.key = 'full')
df_filter_nested <- df %>%
filter(c >= 95) %>% ##this is the key step
group_by(a) %>%
nest(.key = 'filtered')
## Desired outcome - one data frame with 2 nested list-columns: one full and one filtered.
## How to achieve this without breaking it out into 2 separate data frames?
df_nested <- df_full_nested %>%
left_join(df_filter_nested, by = 'a')
对象看起来像这样:
> df
# A tibble: 10 x 3
a b c
<chr> <int> <int>
1 y 8 93
2 x 9 94
3 y 10 99
4 x 5 97
5 y 2 100
6 y 3 95
7 x 7 96
8 y 6 92
9 x 4 91
10 x 1 98
> df_full_nested
# A tibble: 2 x 2
a full
<chr> <list>
1 y <tibble [5 x 2]>
2 x <tibble [5 x 2]>
> df_filter_nested
# A tibble: 2 x 2
a filtered
<chr> <list>
1 y <tibble [3 x 2]>
2 x <tibble [3 x 2]>
> df_nested
# A tibble: 2 x 3
a full filtered
<chr> <list> <list>
1 y <tibble [5 x 2]> <tibble [4 x 2]>
2 x <tibble [5 x 2]> <tibble [4 x 2]>
所以,这行得通。但它不干净。在现实生活中,我按几个栏目分组,这意味着我也必须加入几个栏目...它很快就变得毛茸茸的。
我想知道是否有办法将过滤器应用于嵌套列。这样,我就可以在同一个对象中操作。代码更简洁、更易懂。
我认为它看起来像
df_full_nested %>% mutate(filtered = map(full, ...))
但我不确定如何正确映射filter()
谢谢!
您可以使用 map(full, ~ filter(., c >= 95))
,其中 .
代表单独的嵌套 tibble,您可以对其应用 filter直接:
df_nested_2 <- df_full_nested %>% mutate(filtered = map(full, ~ filter(., c >= 95)))
identical(df_nested, df_nested_2)
# [1] TRUE
我正在尝试使用 purrr
包的 map()
将 filter()
函数应用于存储在嵌套数据框中的数据。
“为什么不先过滤,然后嵌套? - 你可能会问。
这会奏效(我将使用这样的过程展示我想要的结果),但我正在寻找使用 purrr
来实现它的方法。
我只想有一个数据框,有两个列表列,都是嵌套数据框 - 一个完整的和一个过滤的。
我现在可以通过执行 nest()
两次来实现它:一次针对所有数据,第二次针对过滤后的数据:
library(tidyverse)
df <- tibble(
a = sample(x = rep(c('x','y'),5), size = 10),
b = sample(c(1:10)),
c = sample(c(91:100))
)
df_full_nested <- df %>%
group_by(a) %>%
nest(.key = 'full')
df_filter_nested <- df %>%
filter(c >= 95) %>% ##this is the key step
group_by(a) %>%
nest(.key = 'filtered')
## Desired outcome - one data frame with 2 nested list-columns: one full and one filtered.
## How to achieve this without breaking it out into 2 separate data frames?
df_nested <- df_full_nested %>%
left_join(df_filter_nested, by = 'a')
对象看起来像这样:
> df
# A tibble: 10 x 3
a b c
<chr> <int> <int>
1 y 8 93
2 x 9 94
3 y 10 99
4 x 5 97
5 y 2 100
6 y 3 95
7 x 7 96
8 y 6 92
9 x 4 91
10 x 1 98
> df_full_nested
# A tibble: 2 x 2
a full
<chr> <list>
1 y <tibble [5 x 2]>
2 x <tibble [5 x 2]>
> df_filter_nested
# A tibble: 2 x 2
a filtered
<chr> <list>
1 y <tibble [3 x 2]>
2 x <tibble [3 x 2]>
> df_nested
# A tibble: 2 x 3
a full filtered
<chr> <list> <list>
1 y <tibble [5 x 2]> <tibble [4 x 2]>
2 x <tibble [5 x 2]> <tibble [4 x 2]>
所以,这行得通。但它不干净。在现实生活中,我按几个栏目分组,这意味着我也必须加入几个栏目...它很快就变得毛茸茸的。
我想知道是否有办法将过滤器应用于嵌套列。这样,我就可以在同一个对象中操作。代码更简洁、更易懂。
我认为它看起来像
df_full_nested %>% mutate(filtered = map(full, ...))
但我不确定如何正确映射filter()
谢谢!
您可以使用 map(full, ~ filter(., c >= 95))
,其中 .
代表单独的嵌套 tibble,您可以对其应用 filter直接:
df_nested_2 <- df_full_nested %>% mutate(filtered = map(full, ~ filter(., c >= 95)))
identical(df_nested, df_nested_2)
# [1] TRUE