【问题标题】:Combine Dataframe based on value in row in R根据R中行中的值组合Dataframe
【发布时间】:2018-12-18 12:12:25
【问题描述】:

我有 5 个数据帧,每个数据帧都有不同的行数。我需要根据每个数据帧的 col1 中的值将它们合并在一起。观察

df1 <- read.table(text="
   col1    col2
    A        5
    B        3
    C        6
    E        7", header=TRUE, stringsAsFactors=FALSE)

df2 <- read.table(text="
   col1    col2
    A        5
    B        6
    C       7
    M       8
    Z       9", header=T, stringsAsFactors=FALSE)

但我需要它来生产:

   newdf
     col1    col2(#from df1)   col3(#from df2)
      A          5                  5
      B          3                  6
      C          6                  7  
      E          7                  0
      M          0                  8
      Z          0                  9

我曾尝试一次合并几个by='col1',但没有成功。有什么建议吗?

我尝试过的:

posidf<-merge(df1,df2,df3,df4,df5,all.x=TRUE)
#wont execute
posidf<-merge(df1,df2,df3,df4,df5,by="col1",all.x=TRUE)
#wont execute
posidf<-merge(df1,df2,df3,df4,df5,by="col1")
Error in fix.by(by.x, x) : 
'by' must specify one or more columns as numbers, names or logical

【问题讨论】:

  • 您的合并命令到底是什么样的? “无济于事”究竟是什么意思?你收到错误信息了吗?您是否得到了超出预期的输出?问题是缺少行吗?您是否尝试设置all= 参数?
  • @MrFlick 已编辑。我也试过'all-'。 No Avail 意味着它没有成功。
  • merge() 只需要两个 data.frames。你不能传入任意数量的它们吗?查看?merge 帮助页面。您将不得不反复调用 merge(merge(merge(a,b), c, d) 之类的东西。您是否仅使用两个数据框进行了尝试,就像您在问题中实际包含的示例一样?

标签: r merge


【解决方案1】:

我怀疑您正在寻找类似以下示例的内容:

merge(df1, df2, by = "col1", all.x=TRUE, all.y=TRUE)

编辑:

col1 <- c('A', 'B', 'C', 'E')
col2 <- c(5, 3, 6 ,7)
df1 <- data.frame(col1, col2)

col1 <- c('A', 'B', 'C', 'M', 'Z')
col2 <- c(5, 6, 7 ,8, 9)
df2 <- data.frame(col1, col2)

col1 <- c('A', 'B', 'C')
col2 <- c(10, 29, 7)
df3 <- data.frame(col1, col2)

col1 <- c('A', 'S', 'T')
col2 <- c(7 ,8, 9)
df4 <- data.frame(col1, col2)

col1 <- c('B', 'C')
col2 <- c(7 ,8)
df5 <- data.frame(col1, col2)

frame_list <- list(df1, df2, df3, df4, df5)
frame_names <- list('df1', 'df2', 'df3', 'df4', 'df5')
counter <- 0

df <- data.frame(Date=as.Date(character()),
                 File=character(), 
                 User=character(), 
                 stringsAsFactors=FALSE) 

df <- data.frame(matrix(ncol = 2, nrow = 0))
colnames(df) <- c("col1","col2")

for (d in frame_list) {
  counter <- counter + 1
  colnames(d) <- c("col1", paste0('col2_',frame_names[counter]))
  df <- merge(df, d, by = "col1", all.x=TRUE, all.y=TRUE)
}

df$col2 <- NULL
df[is.na(df)] <- 0

【讨论】:

  • 查看更新后的问题。问题似乎是 OP 正在尝试合并 5 个 data.frames,而不仅仅是 2 个。这似乎并没有解决这个问题。
【解决方案2】:

我猜你想要的是一个 full_join。使用dplyr

library(dplyr)

df1 <- data.frame(
  col1 = c("A", "B", "C", "E"),
  col2 = c(5, 3, 6, 7)
)

df2 <- data.frame(
  col1 = c("A", "B", "C", "M", "Z"),
  col2 = c(5, 6, 7, 8, 9)
)


df_merged <- full_join(x = df1, y = df2, by = "col1") 

如果您想要 0 而不是 NA,请将其替换为

df_merged[is.na(df_merged)] &lt;- 0

  col1 col2.x col2.y
1    A      5      5
2    B      3      6
3    C      6      7
4    E      7      0
5    M      0      8
6    Z      0      9

编辑多个数据框

将它们存储在一个列表中,并使用reduce 与各自的连接,这里是full_join

set.seed(123)
df_list <- replicate(5, data.frame(col1 = LETTERS[sample(1:26, 5)], col2 = sample(1:9, 5)), simplify = F)
reduce(df_list, full_join, by = "col1")

   col1 col2.x col2.y col2.x.x col2.y.y col2
1     E      9     NA       NA        1    4
2     F      5     NA       NA       NA   NA
3     N      2     NA       NA        8   NA
4     X      7      4       NA       NA    6
5     P      8     NA       NA        5   NA
6     D     NA      8       NA       NA   NA
7     Q     NA      5       NA       NA   NA
8     J     NA      1       NA       NA   NA
9     U     NA      2       NA        9    8
10    V     NA     NA        1       NA   NA
11    M     NA     NA        7       NA   NA
12    B     NA     NA        8       NA   NA
13    H     NA     NA        9       NA   NA
14    I     NA     NA        4       NA   NA
15    K     NA     NA       NA        6   NA
16    W     NA     NA       NA       NA    9
17    O     NA     NA       NA       NA    3

但正如@zx8754 在评论中建议的那样:从这里复制Simultaneously merge multiple data.frames in a list

【讨论】:

  • 查看更新后的问题。问题似乎是 OP 正在尝试合并 5 个 data.frames,而不仅仅是 2 个。这似乎并没有解决这个问题。
  • 我明白了,更新了从stackoverflow.com/questions/8091303/… 复制的响应,正如@zx8754 所建议的那样
【解决方案3】:

假设您的合并看起来像这样,并且您的示例代表您的数据,则没有问题。

newdf <- merge(x = df1, y = df2,'col1')

##  col1 col2.x col2.y
##1    A      5      5
##2    B      3      6
##3    C      6      7

如果这不是您期望的输出,您可能需要查看不同类型的合并:内连接(上)、外连接左外右外

外部联接

merge(x = df1, y = df2, by = 'col1', all = TRUE)

##  col1 col2.x col2.y
##1    A      5      5
##2    B      3      6
##3    C      6      7
##4    E      7     NA
##5    M     NA      8
##6    Z     NA      9

左外

merge(x = df1, y = df2, by = 'col1', all.x = TRUE)

##  col1 col2.x col2.y
##1    A      5      5
##2    B      3      6
##3    C      6      7
##4    E      7     NA

右外

merge(x = df1, y = df2, by = 'col1', all.y = TRUE)

##  col1 col2.x col2.y
##1    A      5      5
##2    B      3      6
##3    C      6      7
##4    M     NA      8
##5    Z     NA      9

【讨论】:

  • 查看更新后的问题。问题似乎是 OP 正在尝试合并 5 个 data.frames,而不仅仅是 2 个。这似乎并没有解决这个问题。
  • 谢谢。假设这个例子对问题是准确的。我将编辑一个新的回复
  • 我同意这个例子具有误导性。但我也认为@zx8754 建议的副本解决了这个问题。
猜你喜欢
  • 2015-09-16
  • 1970-01-01
  • 2022-06-21
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多