将数据框名称添加为列

时间:2018-07-13 14:51:00

标签: r dataframe lapply

我想合并多个数据框,但在此之前,我想在新列的每个条目中将数据框的名称添加为字符串。我快到了,但是看不到问题。代码:

df1 <- data.frame("X1"=c(1,1),"X2"=c(1,1))
df2 <- data.frame("X1"=c(2,2),"X2"=c(2,2))
df3 <- data.frame("X1"=c(3,3),"X2"=c(3,3))

addCol <- function(df){df$newCol <- deparse(substitute(df)); df} 
# Extracts name of dataframe and writes it into entries of newCol

alldfsList <- lapply(list(df1,df2,df3), function(df) x <- addCol(df)) 
# Should apply addCol function to all dataframes, generates a list of lists

alldfs <- do.call(rbind, alldfsList) # Converts list of lists into dataframe

问题是第二个命令没有将数据帧的名称写入列条目,而是将占位符“ df”写入列。但是,当我将addCol函数手动应用于单个数据框时,它可以工作。你能帮我吗?谢谢!

输出:

> alldfs

  X1 X2 newCol
1  1  1     df
2  1  1     df
3  2  2     df
4  2  2     df
5  3  3     df
6  3  3     df
> 

应用于单个df作品的功能:

> addCol(df1)

  X1 X2 newCol
1  1  1    df1
2  1  1    df1
> 

2 个答案:

答案 0 :(得分:0)

最简单的方法是使用dplyr::bind_rows

library(dplyr)
bind_rows(lst(df1,df2,df3),.id="newCol")
#   newCol X1 X2
# 1    df1  1  1
# 2    df1  1  1
# 3    df2  2  2
# 4    df2  2  2
# 5    df3  3  3
# 6    df3  3  3

答案 1 :(得分:0)

Moody_Mudskipper answer是一个更好的解决方案,这是为了让您了解您的代码正在发生什么。

substitute帮助页面上:

  

substitute返回(未求值的)表达式expr的解析树,替换为env中绑定的任何变量

当在lapply中的函数内运行addCol时,replace从该环境获取名称。看看在lapply中更改语法时会发生什么:

> lapply(list(df1,df2,df3), function(x) x <- addCol(x)) 
[[1]]
  X1 X2 newCol
1  1  1      x
2  1  1      x

[[2]]
  X1 X2 newCol
1  2  2      x
2  2  2      x

[[3]]
  X1 X2 newCol
1  3  3      x
2  3  3      x

您需要使用其他方法来获取对象名称。或更改代码,使函数具有名称作为输入。这是一个示例:

addCol <- function(df.name) {
  dataf <- get(df.name)
  dataf$newCol <- df.name
  return(dataf)
}

> do.call(rbind, lapply(ls(pattern='df'), addCol))
  X1 X2 newCol
1  1  1    df1
2  1  1    df1
3  2  2    df2
4  2  2    df2
5  3  3    df3
6  3  3    df3