R 将列名传递给函数而不是字符串

问题描述

我正在尝试将列名传递给以下函数

unnest_dt <- function(tbl,...) {
    tbl <- as.data.table(tbl)
    col <- ensyms(...)
    clnms <- syms(setdiff(colnames(tbl),as.character(col)))
    tbl <- as.data.table(tbl)
    tbl <- eval(
      expr(tbl[,lapply(.SD,unlist),by = list(!!!clnms),.SDcols = as.character(col)])
   )
   colnames(tbl) <- c(as.character(clnms),as.character(col))
   tbl
}

函数是为取消嵌套具有多个列表列的数据框而构建的。考虑以下对虚拟数据的函数实现。

library(tibble)
df <- tibble(
  a = LETTERS[1:5],b = LETTERS[6:10],list_column_1 = list(c(LETTERS[1:5]),"F","G","H","I"),list_column_2 = list(c(LETTERS[1:5]),"I")
 )

df <- unnest_dt2(df,list_column_1,list_column_2)

它达到了目的。但是,我正在尝试遍历此函数,并且需要将列名传递给它。例如,我希望能够执行以下操作:

library(dplyr)
col <- colnames(df %>% select_if(is.list))
df <- unnest_dt2(df,col)

这会产生错误。 " [.data.table(tbl,by = list(a,b,: 'by' 或 'keyby' 的列或表达式 3 是类型列表。不要引用列名。用法:DT[,sum(colC),by=list(colA,month(colB))] "

有谁知道我该如何处理这个问题?任何帮助将不胜感激。

解决方法

您可以更改函数以使用字符向量。

unnest_dt <- function(tbl,...) {
  tbl <- as.data.table(tbl)
  col <- c(...)
  clnms <- syms(setdiff(colnames(tbl),col))
  tbl <- as.data.table(tbl)
  tbl <- eval(
    expr(tbl[,lapply(.SD,unlist),by = list(!!!clnms),.SDcols = as.character(col)])
  )
  colnames(tbl) <- c(as.character(clnms),as.character(col))
  tbl
}

然后使用:

unnest_dt(df,col)

#   a b list_column_1 list_column_2
#1: A F             A             A
#2: A F             B             B
#3: A F             C             C
#4: A F             D             D
#5: A F             E             E
#6: B G             F             F
#7: C H             G             G
#8: D I             H             H
#9: E J             I             I