【问题标题】:Concatenate data frames with different lengths [duplicate]连接不同长度的数据帧[重复]
【发布时间】:2017-06-26 21:10:24
【问题描述】:

我有许多不同长度的data.frames,我想将它们逐个连接到R中的row.names,如果一个data.frame错过了一些名称,则用0填充该值。例如

df1

A 1
B 1
C 1
D 1

df2

C 2
D 2
E 2

我想要的是

New_df

A 1 0
B 1 0
C 1 2
D 1 2
E 0 2

尝试了几种方法,但都没有奏效。 谢谢!!

【问题讨论】:

  • 我们可以假设您的原始数据框包含任何NA吗?这将简化使用0s 初始化缺失列的答案...
  • rbindlist from data.table with use.names = T 会自动为你做这件事!但是你必须使用 data.table 包而不是基本 R。

标签: r dataframe merge concatenation


【解决方案1】:

由于 OP 想要合并 许多 data.frames,使用Reduce 是有意义的。首先,您必须将您的 dfs 放在一个列表中并像这样使用Reduce

df1 <- read.table(text="ID Val1
A 1
B 1
C 1
D 1",header=TRUE,stringsAsFactors=FALSE)

df2 <- read.table(text="ID Val2
C 2
D 2
E 2",header=TRUE,stringsAsFactors=FALSE)

df3 <- read.table(text="ID Val3
C 2
D 2
F 4",header=TRUE,stringsAsFactors=FALSE)

df_list <- list(df1,df2,df3)

res <- Reduce(function(x, y) merge(x, y, by="ID", all=TRUE), df_list)
res[is.na(res)] <- 0

  ID Val1 Val2 Val3
1  A    1    0    0
2  B    1    0    0
3  C    1    2    2
4  D    1    2    2
5  E    0    2    0
6  F    0    0    4

【讨论】:

  • 有效!非常感谢!
【解决方案2】:

对于要合并的数据框超过 2 个的情况:

df1 <- read.table(text="A 1
                  B 1
                  C 1
                  D 1", stringsAsFactor=F)

df2 <- read.table(text="C 2
                  D 2
                  E 2", stringsAsFactor=F)

dfs <- list(df1, df2)
df_new <- Reduce(function(...) merge(..., all=T, by="V1"), dfs)
df_new[is.na(df_new)] <- 0

【讨论】:

    【解决方案3】:
    col1<-c("A", "B", "C","D")
    col2<-c(1,1,1,1)
    df1<-data.frame(col1, col2)
    
    col1<-c("C", "D", "E")
    col2<-c(2,2,2)
    df2<-data.frame(col1, col2)
    
    
    df3<-rbind(df1, df2)
    df4<-data.frame(unique(df3$col1))
    colnames(df4)[1]<-"ID"
    df5<-left_join(df4, df1, by=c("ID"="col1"))
    df6<-left_join(df5,df2, by=c("ID"="col1"))
    df6[is.na(df6)] <- 0
    

    【讨论】:

    • 为了完整起见,您可能需要添加 library(dplyr)。但即使你这样做,OP 也希望合并两个以上的数据帧。我认为这不是 OP 想要的。
    【解决方案4】:

    对 rsmith45 的回答稍作修改:

    library(tidyverse)
    df1 <-
      data_frame(id = c("A", "B", "C", "D"),
                 val_1 = c(1, 1, 1, 1))
    df2 <-
      data_frame(id = c("C", "D", "E"),
                 val_2 = c(2, 2, 2))
    
    new_df <- full_join(df1, df2) %>%
      replace_na(list(val_1 = 0, val_2 = 0))
    
    > new_df
    # A tibble: 5 x 3
         id val_1 val_2
      <chr> <dbl> <dbl>
    1     A     1     0
    2     B     1     0
    3     C     1     2
    4     D     1     2
    5     E     0     2
    

    replace_na 很酷,因为您可以使用它来根据列用其他值填充 NA:

    new_df <- full_join(df1, df2) %>%
      replace_na(list(val_1 = -99, val_2 = -1))
    
    > new_df
    # A tibble: 5 x 3
         id val_1 val_2
      <chr> <dbl> <dbl>
    1     A     1    -1
    2     B     1    -1
    3     C     1     2
    4     D     1     2
    5     E   -99     2
    

    【讨论】:

    • 哎呀,我现在看到 op 想要很多 dfs。 reduce ycw 的回答很棒!。
    猜你喜欢
    • 1970-01-01
    • 2017-04-06
    • 2016-11-03
    • 2016-08-18
    • 2023-03-10
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    相关资源
    最近更新 更多