示例数据
我有一个数据框列表,每个数据框有两列:1。变量名,2。整数。
df3 <- df2 <- df1 <- data.frame(Variable = LETTERS[1:5], Value = sample(10:20, 5, replace = TRUE))
df.list <- list(df1 = df1, df2 = df2, df3 = df3)
df.list
# $df1
# Variable Value
# 1 A 17
# 2 B 16
# 3 C 16
# 4 D 18
# 5 E 10
#
# $df2
# Variable Value
# 1 A 17
# ...
我想做什么
列表中的每个数据框都已命名。我想提取数据框的名称,并使用它来重命名该数据框中的第二列:
# $df1
# Variable df1
# 1 A 17
# 2 B 16
# 3 C 16
# 4 D 18
# 5 E 10
#
# $df2
# Variable df2
# 1 A 17
# ...
我尝试过的事情
我已经使用deparse(substitute()
编写了一个函数来执行此操作,并通过sub()
编写正则表达式模式匹配:
mod.name <- function(x) {
nx <- deparse(substitute(x))
ny <- sub(".*\\$", "", nx)
names(x)[2] <- ny
x
}
在列表中的单个数据框架上进行测试时,它可以工作:
mod.name(df.list$df3)
df.list$df3
# Variable df3
# 1 A 17
# 2 B 16
# 3 C 16
# 4 D 18
# 5 E 10
但是,当使用lapply
对列表中的所有数据框执行此操作时,它不会:
lapply(df.list, mod.name)
df.list
# $df1
# Variable X[[i]]
# 1 A 17
# 2 B 16
# 3 C 16
# 4 D 18
# 5 E 10
#
# $df2
# Variable X[[i]]
# 1 A 17
# ...
当然,之前在StackOverflow上讨论过将deparse(substitute()
与lapply()
一起使用的问题,但我无法获得任何解决方案here,here或here为我工作。
答案 0 :(得分:2)
您不需要deparse(substitute(.))
。
nms <- setNames(, names(df.list))
df.list2 <- lapply(nms, function(x){
names(df.list[[x]])[2] <- x
df.list[[x]]
})
df.list2
修改强>
在下面的评论中提到Frank后,我已将nms <- names(df.list)
更改为nms <- setNames(, names(df.list))
,并将输出列表的名称更改为df.list2
。
答案 1 :(得分:2)
从技术上讲,这符合既定目标:
Map(function(x,y){ names(y)[[2]] <- x; y }, names(df.list), df.list)
OP表示他们最终的目标是cbind
列在一起(大概是因为Variable
列在所有表中都是相同的),所以这里有一些其他的想法。
rbind
并重新塑造。要实现这一目标,如果所有变量属于同一类型(例如,整数或浮点数),我只会以长格式存储数据:< / p>
library(data.table)
DT = rbindlist(df.list, id = "src")
src Variable Value
1: df1 A 17
2: df1 B 11
3: df1 C 20
4: df1 D 10
5: df1 E 19
6: df2 A 17
7: df2 B 11
8: df2 C 20
9: df2 D 10
10: df2 E 19
11: df3 A 17
12: df3 B 11
13: df3 C 20
14: df3 D 10
15: df3 E 19
从那里,您可以使用
返回宽屏格式dcast(DT, Variable ~ src)
Variable df1 df2 df3
1: A 17 17 17
2: B 11 11 11
3: C 20 20 20
4: D 10 10 10
5: E 19 19 19
cbind
。如果列的类型不同,可以将它们放在一起
as.data.table(c(df.list[[1]][1], lapply(df.list, `[`, -1)))
Variable df1.Value df2.Value df3.Value
1: A 17 17 17
2: B 11 11 11
3: C 20 20 20
4: D 10 10 10
5: E 19 19 19
如果您正在使用这样的data.table,则可以使用setnames
来更改列名。
OP在评论中提到了这两个想法。我只是说明了代码细节。
无论哪种方式,我认为坚持使用一个表格将更容易进行后续分析。