r - 在列表中添加多个数据框
问题描述
我觉得这应该有一个非常简单/优雅的解决方案,但我就是找不到。(我对 r 比较陌生,所以这并不奇怪。)
我有一个(大)嵌套列表,其中包含我试图添加在一起的 data.frames。这是创建一些示例数据的代码:
#Create data frames nested in a list
for (i in 1:6) {
for (j in 1:4) {
assign(paste0("v", j), sample.int(100,4))
}
assign(paste0("df", i), list(cbind(v1, v2, v3, v4)))
}
inner1 <- list(data1 = df1, data2 = df2)
inner2 <- list(data1 = df3, data2 = df4)
inner3 <- list(data1 = df5, data2 = df6)
outer <- list(group1 = inner1, group2 = inner2, group3 = inner3)
我需要将所有标记data1
在一起的数据框和所有的数据框加data2
在一起。如果它们不是这种嵌套列表格式,我会这样做:
data1.tot <- df1 + df3 + df5
data2.tot <- df2 + df4 + df6
因为它们在列表中,所以我认为可能有lapply
解决方案并尝试了:
grp <- c("group1", "group2", "group3") #vector of groups to sum across
datas <- lapply(outer, "[[", "data1") #select "data1" from all groups
tot.datas <- lapply(datas[grp], "+") #to sum across selected data
#I know these last two steps can be combined into one but it helps me keep everything straight to separate them
但它返回Error in FUN(left): invalid argument to unary operator
是因为我将数据列表作为x
.
我还查看了类似这样的其他解决方案:从数据框列表中将选定的数据框添加在一起
但是我的数据的嵌套结构让我不确定如何将该解决方案转化为我的问题。
需要注意的是,我正在使用的数据是 GCHN 每日数据,所以结构不是我的设计。任何帮助将不胜感激。
更新:我已经使用@Parfait 的建议部分想出了一个修复Reduce
,但现在我需要自动化它。我正在研究使用for
循环的解决方案,因为这让我可以更好地控制我正在访问的元素,但我对其他想法持开放态度。这是有效的手动解决方案:
get.df <- function(x, y, z) {
# function to pull out the desired data.frame from the list
# x included as argument to make function applicable to my real data
output <- x[[y]][[z]]
output[[1]]
}
output1 <- get.df(x = outer, y = "group1", z = "data1")
output2 <- get.df(x = outer, y = "group2", z = "data1")
data1 <- list(output1, output2)
data1.tot <- Reduce(`+`, data1)
使用我的示例数据,我想在 2 个数据类型(“data1”和“data2”)和 3 个组(“group1”、“group2”、“group3”)上循环。我正在研究一个for
循环解决方案,但在如何保存output1
和output2
在列表中苦苦挣扎。我的循环现在看起来像这样:
dat <- c("data1", "data2")
grp <- c("group1", "group2", "group3")
for(i in 1:length(dat)) {
for(j in 1:length(grp)) {
assign(paste0("out", j), get.df(x = outer, y = grp[j], z = dat[i]))
}
list(??? #clearly this is where I'm stuck!
}
for
关于循环问题或更好方法的任何建议?
解决方案
考虑Reduce
列表中的哪些工作。这个高阶函数是运行嵌套调用的一种紧凑方式:((df1 + df2) + df3) + ...
.
data1.tot <- Reduce(`+`, lapply(outer, "[[", "data1"))
data2.tot <- Reduce(`+`, lapply(outer, "[[", "data2"))
用随机数据演示
数据
set.seed(9262018)
dfList <- setNames(replicate(6, data.frame(NUM1=runif(50),
NUM2=runif(50),
NUM3=runif(50)), simplify = FALSE),
paste0("df", 1:6))
list2env(dfList, .GlobalEnv)
inner1 <- list(data1 = df1, data2 = df2)
inner2 <- list(data1 = df3, data2 = df4)
inner3 <- list(data1 = df5, data2 = df6)
outer <- list(group1 = inner1, group2 = inner2, group3 = inner3)
输出
data1.tot <- Reduce(`+`, lapply(outer, "[[", "data1"))
head(data1.tot, 10)
# NUM1 NUM2 NUM3
# 1 2.0533870 1.3821609 1.0702992
# 2 2.6046584 1.7260646 1.9699774
# 3 2.2510810 1.6690353 1.4495476
# 4 1.7636879 1.2357098 1.9483906
# 5 1.0189969 2.1191041 1.7466040
# 6 1.3933982 0.7541027 1.0971724
# 7 1.8058803 2.4608417 0.7291335
# 8 1.0763517 1.2494739 1.0480818
# 9 0.7069873 1.5496575 1.2264486
# 10 0.9522526 2.1407523 1.2597422
data2.tot <- Reduce(`+`, lapply(outer, "[[", "data2"))
head(data2.tot, 10)
# NUM1 NUM2 NUM3
# 1 1.7568578 0.9322930 1.5579897
# 2 0.9455063 0.9211592 1.7067779
# 3 1.2698614 0.4623059 0.9426310
# 4 1.6791964 1.4304953 1.2435480
# 5 0.8088625 2.6107952 1.2308862
# 6 1.8202400 2.3511104 1.5676112
# 7 0.9765578 0.8870206 0.6725699
# 8 2.6448770 1.8931751 1.8188512
# 9 1.6114870 1.8632245 0.7452924
# 10 0.9710550 1.8367305 2.0994788
平等测试
all.equal(data1.tot, df1 + df3 + df5)
# [1] TRUE
all.equal(data2.tot, df2 + df4 + df6)
# [1] TRUE
identical(data1.tot, df1 + df3 + df5)
# [1] TRUE
identical(data2.tot, df2 + df4 + df6)
# [1] TRUE
推荐阅读
- git - 在不记录提交 ID 和消息的情况下将更改从 gerrit 带到本地工作区
- azure-devops - Azure DevOps - 帮助/服务台管理系统
- gradle - 我可以做一些判断来在不同的操作系统平台上设置目录前缀吗?
- javascript - Javascript 是否有时间复杂度为 O(log n) 的过滤函数?
- iphone - Where is the Unique Device Identifier (UDID) for an Iphone?
- .net-core - 在 .Net Core OPC UA 客户端上使用基于事件的 MonitoredItem 处理 Sinumerik 警报
- python - CDK ApiMapping 键可能只包含字母、数字和...错误之一
- python - 在另一个文件中使用引发异常的属性
- oracle-adf - JBO-25014:另一个用户使用主键 oracle.jbo.Key[x] 更改了行
- python - Tkinter - 使用循环创建的条目,我如何与单个条目进行交互?