在R中访问对象名称和绑定

时间:2017-08-30 11:40:04

标签: r dplyr

我喜欢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)

1 个答案:

答案 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,返回单个数据集