我喜欢bind_rows
中的dplyr
函数,但我觉得很烦人的是,在传递.id
参数时,它只能在新列中添加数字索引。
我正在尝试编写一个bind_rows_named
函数,但我很难访问对象名称。这按预期工作:
bind_name_to_df <- function(df){
dfname <- deparse(substitute(df))
df %>% mutate(label=dfname)
}
a <- data_frame(stuff=1:10)
bind_name_to_df(a)
但我无法弄清楚如何将其应用于数据框列表,例如使用.dots。我希望这个工作,但我知道我有...
错误的语义。谁能摆脱光明?
b <- data_frame(stuff=1:10)
bind_rows_named <- function(...){
return(
bind_rows(lapply(..., bind_name_to_df)))
}
bind_rows_named(a, b)
答案 0 :(得分:1)
以下是使用base R
bind_named <- function(...){
v1 <- sapply(match.call()[-1], deparse)
dfs <- list(...)
Map(cbind, dfs, label = v1)
}
bind_named(a, b)
#[1]]
# stuff label
#1 1 a
#2 2 a
#3 3 a
#4 4 a
#5 5 a
#6 6 a
#7 7 a
#8 8 a
#9 9 a
#10 10 a
#[[2]]
# stuff label
#1 1 b
#2 2 b
#3 3 b
#4 4 b
#5 5 b
#6 6 b
#7 7 b
#8 8 b
#9 9 b
#10 10 b
或使用tidyverse
library(tidyverse)
bind_named <- function(...) {
nm1 <- quos(...) %>%
map(quo_name)
dfs <- list(...)
dfs %>%
map2(nm1, ~mutate(., label = .y))
}
res <- bind_named(a, b)
res %>%
map(head, 2)
#[[1]]
# stuff label
#1 1 a
#2 2 a
#[[2]]
# stuff label
#1 1 b
#2 2 b
它也可以制成单链
bind_named <- function(...) {
quos(...) %>%
map(quo_name) %>%
map2_df(list(...), ., ~mutate(.data = .x, label = .y))
}
bind_named(a, b)
# A tibble: 20 x 2
# stuff label
# <int> <chr>
# 1 1 a
# 2 2 a
# 3 3 a
# 4 4 a
# 5 5 a
# 6 6 a
# 7 7 a
# 8 8 a
# 9 9 a
#10 10 a
#11 1 b
#12 2 b
#13 3 b
#14 4 b
#15 5 b
#16 6 b
#17 7 b
#18 8 b
#19 9 b
#20 10 b
注意:最初,我们认为OP希望在不同的数据集上创建列并获得list
输出。澄清后,map2
更改为map2_df
,返回单个数据集