R:合并数据框列表
R: Merging lists of data frames
我完全是 R 的菜鸟,我已经尝试(并重试)寻找以下问题的答案,但我无法获得任何建议的解决方案来完成我的工作'有兴趣。
我有两个命名元素列表,每个元素都指向具有相同布局的数据框:
(编辑)
df1 <- data.frame(A=c(1,2,3),B=c("A","B","C"))
df2 <- data.frame(A=c(98,99),B=c("Y","Z"))
lst1 <- c(X=df1,Y=df2)
df3 <- data.frame(A=c(4,5),B=c("D","E"))
lst2 <- c(X=df3)
(编辑 2)
所以在列表中存储多个数据框似乎不是一个好主意,因为它会将数据框转换为列表。因此,我将寻找一种替代方法来存储一组命名数据框。
一般来说,两个元素中的元素名称可能部分重叠、完全重叠或完全不重叠。
我正在寻找一种将两个列表合并为一个列表的方法:
<some-function-sequence>(lst1, lst2)
->
c(X=rbind(df1,df3),Y=df2)
-结果是这样的:
[编辑:语法已更改以正确反映所需结果(数据框列表)]
$X
甲乙
1 1 一个
2 2乙
3 3 摄氏度
4 4 天
5 5 E
$X.B
A B
1 98 Y
2 99 Z
即:
- 如果列表包含相同的元素名称,每个元素名称都指向一个数据框,那么我想 'rbind' 来自这两个数据框的行,并将生成的数据框分配给结果中的相同元素名称列表。
- 否则,应将两个列表中的元素名称和数据框复制到结果列表中。
我尝试了很多讨论的解决方案,例如:
- Can I combine a list of similar dataframes into a single dataframe?
- Combine/merge lists by elements names
- Simultaneously merge multiple data.frames in a list
- Combine/merge lists by elements names (list in list)
- Convert a list of data frames into one data frame
-但我一直未能找到正确的解决方案。一个普遍的问题似乎是数据框最终被 'mapply/sapply/merge/...' 的应用程序转换为列表 - 通常也以我不感兴趣的方式合并 and/or 切片。:)
如有任何帮助,我们将不胜感激!
[解决方案]
解决方案似乎是在收集数据帧时将 c(...)
的使用更改为 list(...)
,之后 Pierre 提出的解决方案似乎给出了预期的结果。
以下解决方案可能不是最有效的方法。但是,如果我解决了你的问题,这应该可行;)
# Example data
# Some vectors
a <- 1:5
b <- 3:7
c <- rep(5, 5)
d <- 5:1
# Some dataframes, data1 and data3 have identical column names
data1 <- data.frame(a, b)
data2 <- data.frame(c, b)
data3 <- data.frame(a, b)
data4 <- data.frame(c, d)
# 2 lists
list1 <- list(data1, data2)
list2 <- list(data3, data4)
# Loop, wich checks for the dataframe names and rbinds dataframes with the same column names
final_list <- list1
used_lists <- numeric()
for(i in 1:length(list1)) {
for(j in 1:length(list2)) {
if(sum(colnames(list1[[i]]) == colnames(list2[[j]])) == ncol(list1[[i]])) {
final_list[[i]] <- rbind(list1[[i]], list2[[j]])
used_lists <- c(used_lists, j)
}
}
}
# Adding the other dataframes, which did not have the same column names
for(i in 1:length(list2)) {
if((i %in% used_lists) == FALSE) {
final_list[[length(final_list) + 1]] <- list2[[i]]
}
}
# Final list, which includes all other lists
final_list
这是一个建议的解决方案,使用 split
和 c
组合相似的术语。请阅读底部的警告:
s <- split(c(lst1, lst2), names(c(lst1,lst2)))
lapply(s, function(lst) do.call(function(...) unname(c(...)), lst))
# $X.A
# [1] 1 2 3 4 5
#
# $X.B
# [1] "A" "B" "C" "D" "E"
#
# $Y.A
# [1] 98 99
#
# $Y.B
# [1] "Y" "Z"
此解决方案基于不将因子作为字符串。它不会抛出错误,但因子将被转换为数字。下面我展示了我如何转换数据以删除因素。如果您需要因素,请告诉我:
df1 <- data.frame(A=c(1,2,3),B=c("A","B","C"), stringsAsFactors=FALSE)
df2 <- data.frame(A=c(98,99),B=c("Y","Z"), stringsAsFactors=FALSE)
lst1 <- c(X=df1,Y=df2)
df3 <- data.frame(A=c(4,5),B=c("D","E"), stringsAsFactors=FALSE)
lst2 <- c(X=df3)
如果数据存储在列表中,我们可以使用:
lapply(split(c(lst1, lst2), names(c(lst1,lst2))), function(lst) do.call(rbind, lst))
我完全是 R 的菜鸟,我已经尝试(并重试)寻找以下问题的答案,但我无法获得任何建议的解决方案来完成我的工作'有兴趣。
我有两个命名元素列表,每个元素都指向具有相同布局的数据框:
(编辑)
df1 <- data.frame(A=c(1,2,3),B=c("A","B","C"))
df2 <- data.frame(A=c(98,99),B=c("Y","Z"))
lst1 <- c(X=df1,Y=df2)
df3 <- data.frame(A=c(4,5),B=c("D","E"))
lst2 <- c(X=df3)
(编辑 2)
所以在列表中存储多个数据框似乎不是一个好主意,因为它会将数据框转换为列表。因此,我将寻找一种替代方法来存储一组命名数据框。
一般来说,两个元素中的元素名称可能部分重叠、完全重叠或完全不重叠。
我正在寻找一种将两个列表合并为一个列表的方法:
<some-function-sequence>(lst1, lst2)
->
c(X=rbind(df1,df3),Y=df2)
-结果是这样的:
[编辑:语法已更改以正确反映所需结果(数据框列表)] $X 甲乙 1 1 一个 2 2乙 3 3 摄氏度 4 4 天 5 5 E
$X.B
A B
1 98 Y
2 99 Z
即:
- 如果列表包含相同的元素名称,每个元素名称都指向一个数据框,那么我想 'rbind' 来自这两个数据框的行,并将生成的数据框分配给结果中的相同元素名称列表。
- 否则,应将两个列表中的元素名称和数据框复制到结果列表中。
我尝试了很多讨论的解决方案,例如:
- Can I combine a list of similar dataframes into a single dataframe?
- Combine/merge lists by elements names
- Simultaneously merge multiple data.frames in a list
- Combine/merge lists by elements names (list in list)
- Convert a list of data frames into one data frame
-但我一直未能找到正确的解决方案。一个普遍的问题似乎是数据框最终被 'mapply/sapply/merge/...' 的应用程序转换为列表 - 通常也以我不感兴趣的方式合并 and/or 切片。:)
如有任何帮助,我们将不胜感激!
[解决方案]
解决方案似乎是在收集数据帧时将 c(...)
的使用更改为 list(...)
,之后 Pierre 提出的解决方案似乎给出了预期的结果。
以下解决方案可能不是最有效的方法。但是,如果我解决了你的问题,这应该可行;)
# Example data
# Some vectors
a <- 1:5
b <- 3:7
c <- rep(5, 5)
d <- 5:1
# Some dataframes, data1 and data3 have identical column names
data1 <- data.frame(a, b)
data2 <- data.frame(c, b)
data3 <- data.frame(a, b)
data4 <- data.frame(c, d)
# 2 lists
list1 <- list(data1, data2)
list2 <- list(data3, data4)
# Loop, wich checks for the dataframe names and rbinds dataframes with the same column names
final_list <- list1
used_lists <- numeric()
for(i in 1:length(list1)) {
for(j in 1:length(list2)) {
if(sum(colnames(list1[[i]]) == colnames(list2[[j]])) == ncol(list1[[i]])) {
final_list[[i]] <- rbind(list1[[i]], list2[[j]])
used_lists <- c(used_lists, j)
}
}
}
# Adding the other dataframes, which did not have the same column names
for(i in 1:length(list2)) {
if((i %in% used_lists) == FALSE) {
final_list[[length(final_list) + 1]] <- list2[[i]]
}
}
# Final list, which includes all other lists
final_list
这是一个建议的解决方案,使用 split
和 c
组合相似的术语。请阅读底部的警告:
s <- split(c(lst1, lst2), names(c(lst1,lst2)))
lapply(s, function(lst) do.call(function(...) unname(c(...)), lst))
# $X.A
# [1] 1 2 3 4 5
#
# $X.B
# [1] "A" "B" "C" "D" "E"
#
# $Y.A
# [1] 98 99
#
# $Y.B
# [1] "Y" "Z"
此解决方案基于不将因子作为字符串。它不会抛出错误,但因子将被转换为数字。下面我展示了我如何转换数据以删除因素。如果您需要因素,请告诉我:
df1 <- data.frame(A=c(1,2,3),B=c("A","B","C"), stringsAsFactors=FALSE)
df2 <- data.frame(A=c(98,99),B=c("Y","Z"), stringsAsFactors=FALSE)
lst1 <- c(X=df1,Y=df2)
df3 <- data.frame(A=c(4,5),B=c("D","E"), stringsAsFactors=FALSE)
lst2 <- c(X=df3)
如果数据存储在列表中,我们可以使用:
lapply(split(c(lst1, lst2), names(c(lst1,lst2))), function(lst) do.call(rbind, lst))