使用区分变量复制数据帧n次

问题描述 投票:1回答:2

我想通过复制foo次来增长n,并将foo的每个副本与新变量的唯一值区分开来。如果n是3,我可以通过以下方式详细说明:

library(tidyverse)

foo <- mtcars %>%
  filter(row_number() < 3)

# desired result
bind_rows(
  foo %>% mutate(key = "a"),
  foo %>% mutate(key = "b"),
  foo %>% mutate(key = "c")
)
#>   mpg cyl disp  hp drat    wt  qsec vs am gear carb key
#> 1  21   6  160 110  3.9 2.620 16.46  0  1    4    4   a
#> 2  21   6  160 110  3.9 2.875 17.02  0  1    4    4   a
#> 3  21   6  160 110  3.9 2.620 16.46  0  1    4    4   b
#> 4  21   6  160 110  3.9 2.875 17.02  0  1    4    4   b
#> 5  21   6  160 110  3.9 2.620 16.46  0  1    4    4   c
#> 6  21   6  160 110  3.9 2.875 17.02  0  1    4    4   c

我正试图找到一种更简约的做法。理想情况下,我想将解决方案纳入foo传递给%>%的一行。

我的(失败的)purrr尝试:

foo %>%
  map_dfr(c("a", "b", "c"), ~ mutate(., key = .x))
r dplyr purrr
2个回答
3
投票

在你尝试使用purrr时,做foo %>%并没有帮助你,因为你不需要foo成为map_dfr的第一个参数。相反,你可以这样做:

map_dfr(c("a", "b", "c"), ~ mutate(foo, key = .x))

如果你想继续使用管道,但是停止将foo作为第一个参数传递,你可以用map_dfr包围{},这会抑制自动参数传递:

foo %>%
    { map_dfr(c("a", "b", "c"), function(x) { mutate(., key = x)}) }

(可能有更优雅的方法使用不同的magrittr管道,我主要坚持%>%


3
投票

我们可以用

library(tidyverse)
set_names(replicate(3, foo, simplify = FALSE), letters[1:3])  %>% 
               bind_rows(.id = 'key')

或者使用uncount

uncount(foo, 3) %>% 
    mutate(key = rep(letters[1:3], each = 2))

或者与unnest

foo %>% 
   mutate(key = list(letters[1:3])) %>% 
   unnest
#  mpg cyl disp  hp drat    wt  qsec vs am gear carb key
#1  21   6  160 110  3.9 2.620 16.46  0  1    4    4   a
#2  21   6  160 110  3.9 2.620 16.46  0  1    4    4   b
#3  21   6  160 110  3.9 2.620 16.46  0  1    4    4   c
#4  21   6  160 110  3.9 2.875 17.02  0  1    4    4   a
#5  21   6  160 110  3.9 2.875 17.02  0  1    4    4   b
#6  21   6  160 110  3.9 2.875 17.02  0  1    4    4   c
© www.soinside.com 2019 - 2024. All rights reserved.