将几个data.frames合并为一个(保留每个rownames)

时间:2017-01-22 20:47:53

标签: r

我输入了数据框BerryOrange

Berry = structure(list(Name = c("ACT", "ACTION", "ACTIVISM", "ACTS", 
"ADDICTION", "ADVANCE"), freq = c(2L, 2L, 1L, 1L, 1L, 1L)), .Names = c("Name", 
"freq"), row.names = c(NA, 6L), class = "data.frame")

Orange = structure(list(Name = c("ACHIEVE", "ACROSS", "ACT", "ACTION", 
"ADVANCE", "ADVANCING"), freq = c(1L, 3L, 1L, 1L, 1L, 1L)), .Names = c("Name", 
"freq"), row.names = c(NA, 6L), class = "data.frame")

运行以下操作将为我提供所需的output

output = t(merge(Berry,Orange, by = "Name", all = TRUE))
rownames(output) = c("","Berry","Orange")
colnames(output) = output[1,]
output = output[2:3,]
output = data.frame(output)

但是,现在我必须从 72 数据框创建output,类似于BerryOrange。由于merge似乎一次只能使用两个data.frame,因此我不确定对我来说最好的方法是什么。我尝试rbind.fill保留了值,但丢失了Names。我找到了thisthis,但无法自行找出解决方案。

为了提供可重现的示例,还有一个data.frame

Apple = structure(list(Name = c("ABIDING", "ABLE", "ABROAD", "ACROSS", 
"ACT", "ADVANTAGE"), freq = c(1L, 1L, 1L, 4L, 2L, 1L)), .Names = c("Name", 
"freq"), row.names = c(NA, 6L), class = "data.frame")

我试图弄清楚如何从outputAppleBerry获取Orange。我正在寻找一种适用于多个数据帧的解决方案,最好不要手动提供数据帧。

您可以假设要获取output的数据框架名称可在列表df_names中使用:

 df_names = c("Apple","Berry","Orange")

或者,您也可以假设需要处理data.frame中的每个Global Environment以创建output

2 个答案:

答案 0 :(得分:4)

如果您在环境中拥有所有数据框,则可以将它们放入命名列表,然后使用包 reshape2 重新整形列表。如果需要,您可以将第一列设置为行名称。

library(reshape2)
dcast(melt(Filter(is.data.frame, mget(ls()))), L1 ~ Name)
#       L1 ABIDING ABLE ABROAD ACHIEVE ACROSS ACT ACTION ACTIVISM ACTS ADDICTION ADVANCE ADVANCING ADVANTAGE
# 1  Apple       1    1      1      NA      4   2     NA       NA   NA        NA      NA        NA         1
# 2  Berry      NA   NA     NA      NA     NA   2      2        1    1         1       1        NA        NA
# 3 Orange      NA   NA     NA       1      3   1      1       NA   NA        NA       1         1        NA

注意:这假设您的所有数据都在全局环境中,除了在此处使用的数据框外,不存在其他数据框。

答案 1 :(得分:1)

我们可以使用tidyverse

library(dplyr)
library(tidyr)
list(Apple = Apple, Orange = Orange, Berry = Berry)  %>%
          bind_rows(.id = "objName") %>% 
          spread(Name, freq, fill = 0) 
#    objName ABIDING ABLE ABROAD ACHIEVE ACROSS ACT ACTION ACTIVISM ACTS ADDICTION ADVANCE ADVANCING ADVANTAGE
#1   Apple       1    1      1       0      4   2      0        0    0         0       0         0         1
#2   Berry       0    0      0       0      0   2      2        1    1         1       1         0         0
#3  Orange       0    0      0       1      3   1      1        0    0         0       1         1         0

由于您有72个data.frames,最好不要在全局环境中创建所有这些对象。而是,在list中读取数据集文件,然后进行处理。假设,如果文件都在工作目录中

files <- list.files(pattern = ".csv")
lapply(files, read.csv, stringsAsFactors=FALSE) 

然后按上述bind_rows进行处理。由于目前尚不清楚文件名,我们无法评论如何创建&#39; objName&#39;