在R中添加2个数据帧而不会丢失列

问题描述 投票:1回答:5

我在R(df1,df2)中有2个数据帧。

A C D
1 1 1
2 2 2

df2为

A B C
1 1 1
2 2 2

如何合并这两个数据帧以产生以下输出?

A B C D
2 1 2 1
4 2 4 2

对列进行排序并添加列值。两个DF都具有相同的行数。先感谢您。创建DF的代码:

df1 <- data.frame("A" = 1:2, "C" = 1:2, "D" = 1:2)
df2 <- data.frame("A" = 1:2, "B" = 1:2, "C" = 1:2)
r dataframe merge
5个回答
3
投票
nm1 = names(df1)
nm2 = names(df2)
nm = intersect(nm1, nm2)

if (length(nm) == 0){                  # if no column names in common
    cbind(df1, df2)
} else {                               # if column names in common
    cbind(df1[!nm1 %in% nm2],          # columns only in df1
          df1[nm] + df2[nm],           # add columns common to both
          df2[!nm2 %in% nm1])          # columns only in df2
}
#  D A C B
#1 1 2 2 1
#2 2 4 4 2

2
投票

你可以试试:

library(tidyverse)

list(df2, df1) %>%
  map(rownames_to_column) %>%
  bind_rows %>%
  group_by(rowname) %>%
  summarise_all(sum, na.rm = TRUE)

# A tibble: 2 x 5
  rowname     A     B     C     D
  <chr>   <int> <int> <int> <int>
1 1           2     1     2     1
2 2           4     2     4     2

0
投票

通过使用left_join()dplyr,你不会失去专栏

library(tidyverse)

dat1 <- tibble(a = 1:10,
               b = 1:10,
               c = 1:10)

dat2 <- tibble(c = 1:10,
               d = 1:10, 
               e = 1:10)

left_join(dat1, dat2, by = "c")
#> # A tibble: 10 x 5
#>        a     b     c     d     e
#>    <int> <int> <int> <int> <int>
#>  1     1     1     1     1     1
#>  2     2     2     2     2     2
#>  3     3     3     3     3     3
#>  4     4     4     4     4     4
#>  5     5     5     5     5     5
#>  6     6     6     6     6     6
#>  7     7     7     7     7     7
#>  8     8     8     8     8     8
#>  9     9     9     9     9     9
#> 10    10    10    10    10    10

reprex package创建于2019-01-16(v0.2.1)


0
投票
allnames <- sort(unique(c(names(df1), names(df2))))

df3 <- data.frame(matrix(0, nrow = nrow(df1), ncol = length(allnames)))
names(df3) <- allnames

df3[,allnames %in% names(df1)] <- df3[,allnames %in% names(df1)] + df1
df3[,allnames %in% names(df2)] <- df3[,allnames %in% names(df2)] + df2

df3
  A B C D
1 2 1 2 1
2 4 2 4 2

0
投票

这是一个有趣的基础R方法与Reduce

Reduce(cbind,
       list(Reduce("+", list(df1[intersect(names(df1), names(df2))],
                             df2[intersect(names(df1), names(df2))])), # sum results
                             df1[setdiff(names(df1), names(df2))], # in df1, not df2
                             df2[setdiff(names(df2), names(df1))])) # in df2, not df1

这回来了

  A C D B
1 2 2 1 1
2 4 4 2 2

这假设df1和df2都有不在另一个中的列。如果不是这样,则必须调整列表。

另请注意,你可以在两个地方用Reduce替换do.call,你会得到相同的结果。

© www.soinside.com 2019 - 2024. All rights reserved.