使用 purrr 映射 dplyr::select
using purrr to map dplyr::select
我有一个数据框,里面有一堆嵌套的数据框,我想对每个嵌套的数据框应用 dplyr::select。这是一个例子
library(tidyverse)
mtcars %>%
group_by(cyl) %>%
nest %>%
mutate(data2 = ~map(data, dplyr::select(.,-mpg)))
我认为这会产生一个包含三列的数据框。 cyl
:气缸数,data
:嵌套数据,data2
:与数据相同,但每个元素不会有 mpg 列。
相反,R 崩溃:
*** caught segfault ***
address 0x7ffc1e445000, cause 'memory not mapped'
Traceback:
1: .Call(`_dplyr_mutate_impl`, df, dots)
2: mutate_impl(.data, dots)
3: mutate.tbl_df(., data2 = ~map(data, dplyr::select(., -mpg)))
4: mutate(., data2 = ~map(data, dplyr::select(., -mpg)))
5: function_list[[k]](value)
6: withVisible(function_list[[k]](value))
7: freduce(value, `_function_list`)
8: `_fseq`(`_lhs`)
9: eval(quote(`_fseq`(`_lhs`)), env, env)
10: eval(quote(`_fseq`(`_lhs`)), env, env)
11: withVisible(eval(quote(`_fseq`(`_lhs`)), env, env))
12: mtcars %>% group_by(cyl) %>% nest %>% mutate(data2 = ~map(data, dplyr::select(., -mpg)))
Possible actions:
1: abort (with core dump, if enabled)
2: normal R exit
3: exit R without saving workspace
4: exit R saving workspace
我意识到如果我在嵌套之前应用 select 操作,我可以获得我想要的列,但这与我的实际问题不太相似。有人可以向我解释我在这里做错了什么吗?感谢您的任何建议。
您需要将 ~
从 map
移动到 select
;或使用@Russ 的评论;当函数(在本例中为 purrr::map
)接受公式作为参数时使用 ~
:
mtcars %>%
group_by(cyl) %>%
nest %>%
mutate(data2 = map(data, ~ select(., -mpg)))
# A tibble: 3 x 3
# cyl data data2
# <dbl> <list> <list>
#1 6 <tibble [7 × 10]> <tibble [7 × 9]>
#2 4 <tibble [11 × 10]> <tibble [11 × 9]>
#3 8 <tibble [14 × 10]> <tibble [14 × 9]>
这里有两种方式:一种是跳过嵌套,只使用 do
,另一种是嵌套,然后使用 map
。 unnest(data2)
然后将其返回到常规数据框中。需要注意的是,我在第一个示例中将 -cyl
包含在 select
中;那是因为否则,您最终会得到 cyl
两次,一次来自分组列,一次来自未嵌套的数据框。
除了个人喜好之外,我不确定其中一个是否比另一个更好。
library(tidyverse)
mtcars %>%
group_by(cyl) %>%
do(data2 = select(., -mpg, -cyl)) %>%
unnest(data2)
#> # A tibble: 32 x 10
#> cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 4 108 93 3.85 2.32 18.6 1 1 4 1
#> 2 4 147. 62 3.69 3.19 20 1 0 4 2
#> 3 4 141. 95 3.92 3.15 22.9 1 0 4 2
#> 4 4 78.7 66 4.08 2.2 19.5 1 1 4 1
#> 5 4 75.7 52 4.93 1.62 18.5 1 1 4 2
#> 6 4 71.1 65 4.22 1.84 19.9 1 1 4 1
#> 7 4 120. 97 3.7 2.46 20.0 1 0 3 1
#> 8 4 79 66 4.08 1.94 18.9 1 1 4 1
#> 9 4 120. 91 4.43 2.14 16.7 0 1 5 2
#> 10 4 95.1 113 3.77 1.51 16.9 1 1 5 2
#> # ... with 22 more rows
mtcars %>%
group_by(cyl) %>%
nest() %>%
mutate(data2 = map(data, function(df) select(df, -mpg))) %>%
unnest(data2)
# same output
另一种解决方案是将 -mpg
"as is" 传递给 map()
,这将正确地将其传递给 select()
。
mtcars %>%
group_by(cyl) %>%
nest %>%
mutate(data2 = map( data, select, -mpg ))
在 R 3.6.1
与 dplyr 0.8.3
一起工作。
我有一个数据框,里面有一堆嵌套的数据框,我想对每个嵌套的数据框应用 dplyr::select。这是一个例子
library(tidyverse)
mtcars %>%
group_by(cyl) %>%
nest %>%
mutate(data2 = ~map(data, dplyr::select(.,-mpg)))
我认为这会产生一个包含三列的数据框。 cyl
:气缸数,data
:嵌套数据,data2
:与数据相同,但每个元素不会有 mpg 列。
相反,R 崩溃:
*** caught segfault *** address 0x7ffc1e445000, cause 'memory not mapped' Traceback: 1: .Call(`_dplyr_mutate_impl`, df, dots) 2: mutate_impl(.data, dots) 3: mutate.tbl_df(., data2 = ~map(data, dplyr::select(., -mpg))) 4: mutate(., data2 = ~map(data, dplyr::select(., -mpg))) 5: function_list[[k]](value) 6: withVisible(function_list[[k]](value)) 7: freduce(value, `_function_list`) 8: `_fseq`(`_lhs`) 9: eval(quote(`_fseq`(`_lhs`)), env, env) 10: eval(quote(`_fseq`(`_lhs`)), env, env) 11: withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 12: mtcars %>% group_by(cyl) %>% nest %>% mutate(data2 = ~map(data, dplyr::select(., -mpg))) Possible actions: 1: abort (with core dump, if enabled) 2: normal R exit 3: exit R without saving workspace 4: exit R saving workspace
我意识到如果我在嵌套之前应用 select 操作,我可以获得我想要的列,但这与我的实际问题不太相似。有人可以向我解释我在这里做错了什么吗?感谢您的任何建议。
您需要将 ~
从 map
移动到 select
;或使用@Russ 的评论;当函数(在本例中为 purrr::map
)接受公式作为参数时使用 ~
:
mtcars %>%
group_by(cyl) %>%
nest %>%
mutate(data2 = map(data, ~ select(., -mpg)))
# A tibble: 3 x 3
# cyl data data2
# <dbl> <list> <list>
#1 6 <tibble [7 × 10]> <tibble [7 × 9]>
#2 4 <tibble [11 × 10]> <tibble [11 × 9]>
#3 8 <tibble [14 × 10]> <tibble [14 × 9]>
这里有两种方式:一种是跳过嵌套,只使用 do
,另一种是嵌套,然后使用 map
。 unnest(data2)
然后将其返回到常规数据框中。需要注意的是,我在第一个示例中将 -cyl
包含在 select
中;那是因为否则,您最终会得到 cyl
两次,一次来自分组列,一次来自未嵌套的数据框。
除了个人喜好之外,我不确定其中一个是否比另一个更好。
library(tidyverse)
mtcars %>%
group_by(cyl) %>%
do(data2 = select(., -mpg, -cyl)) %>%
unnest(data2)
#> # A tibble: 32 x 10
#> cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 4 108 93 3.85 2.32 18.6 1 1 4 1
#> 2 4 147. 62 3.69 3.19 20 1 0 4 2
#> 3 4 141. 95 3.92 3.15 22.9 1 0 4 2
#> 4 4 78.7 66 4.08 2.2 19.5 1 1 4 1
#> 5 4 75.7 52 4.93 1.62 18.5 1 1 4 2
#> 6 4 71.1 65 4.22 1.84 19.9 1 1 4 1
#> 7 4 120. 97 3.7 2.46 20.0 1 0 3 1
#> 8 4 79 66 4.08 1.94 18.9 1 1 4 1
#> 9 4 120. 91 4.43 2.14 16.7 0 1 5 2
#> 10 4 95.1 113 3.77 1.51 16.9 1 1 5 2
#> # ... with 22 more rows
mtcars %>%
group_by(cyl) %>%
nest() %>%
mutate(data2 = map(data, function(df) select(df, -mpg))) %>%
unnest(data2)
# same output
另一种解决方案是将 -mpg
"as is" 传递给 map()
,这将正确地将其传递给 select()
。
mtcars %>%
group_by(cyl) %>%
nest %>%
mutate(data2 = map( data, select, -mpg ))
在 R 3.6.1
与 dplyr 0.8.3
一起工作。