使用数据帧的名称(deparse、substitute和lapply)重命名数据帧列表中的第二列
样本数据 我有一个数据帧列表,每个数据帧有两列:1。变量名,2。整数使用数据帧的名称(deparse、substitute和lapply)重命名数据帧列表中的第二列,r,list,dataframe,rename,lapply,R,List,Dataframe,Rename,Lapply,样本数据 我有一个数据帧列表,每个数据帧有两列: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
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
# ...
我尝试过的
我使用deparse(substitute()
和通过sub()进行正则表达式模式匹配编写了一个函数来实现这一点:
但是,当使用lappy
对列表中的所有数据帧执行此操作时,它不会:
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
# ...
当然,使用deparse(substitute()
和lappy()
的问题在StackOverflow之前已经讨论过了,但是我无法得到任何解决方案,也无法为我工作。您不需要deparse(substitute(.)
nms您不需要deparse(替换(.))
nms从技术上讲,这是为了实现既定目标:
Map(function(x,y){ names(y)[[2]] <- x; y }, names(df.list), df.list)
从那里,您可以使用
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在评论中提到了这两个想法。我只是说明代码的细节
不管是哪种方式,我认为坚持一张表将更便于以后的分析。从技术上讲,这有助于实现既定目标:
Map(function(x,y){ names(y)[[2]] <- x; y }, names(df.list), df.list)
从那里,您可以使用
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在评论中提到了这两个想法。我只是说明代码的细节
不管是哪种方式,我认为坚持一个表会更便于以后的分析。Map(函数(x,y){names(y)[[2]]]@Frank这很有效——谢谢!但是你能解释一下为什么这是个坏主意吗?当然。嵌入一个变量(df1,df2,df3中的1,2,3)作为列名的一部分,意味着您以后必须再次解析该列名。此外,保留一个包含相关内容的data.frames列表,而不是使用rbind
创建一个列表,这将继续导致混乱(需要更多lappy
或mappy
,而不是正常的表操作).Gregor在这里讨论了列表与单个表之间的权衡,Hadley在这里讨论了在列名称中放置变量:因此,在本例中,我将使用data.table::rbindlist(df.list,id=“src”)
(在Gregor的帖子中提到)@Frank谢谢你的解释。很高兴知道。在这种情况下,我的目标是将新命名的第二列和cbind
提取到一个新的数据框中,以便更容易地比较第一列中列出的变量的值是如何变化的,但也许最好先rbind
it,然后再res从长到宽。Map(函数(x,y){names(y)[[2]]]@Frank这很有效——谢谢!但是你能解释一下为什么这是个坏主意吗?当然。嵌入一个变量(df1,df2,df3中的1,2,3)作为列名的一部分,意味着您以后必须再次解析该列名。此外,保留一个包含相关内容的data.frames列表,而不是使用rbind
创建一个列表,这将继续导致混乱(需要更多lappy
或mappy
,而不是正常的表操作).Gregor在这里讨论了列表与单个表之间的权衡,Hadley在这里讨论了在列名称中放置变量:因此,在本例中,我将使用data.table::rbindlist(df.list,id=“src”)
(在Gregor的帖子中提到)@Frank谢谢你的解释。很高兴知道。在这种情况下,我的目标是将新命名的第二列和cbind
提取到一个新的数据框中,以便更容易地比较第一列中列出的变量的值是如何变化的,但也许最好先rbind
it,然后再res从长到宽。@Frank好的,谢谢,我会记住的。编辑答案。@Frank好的,谢谢,我会记住的。编辑答案。
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
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