根据匹配的列名称将两个数据帧加在一起

时间:2019-05-14 17:11:32

标签: r

我有两个数据集,我想根据匹配的列名将它们添加在一起。对于数据集,每一行代表一个研究地点,每一列代表一项调查。每个调查仅限于一个街区。我想根据列名将每个数据集的内容加在一起。

数据集1(1表示已执行调查):

Block A1  A2  A3  A4  A5
    1  0   1   0   0   0
    2  1   0   0   1   0
    3  0   0   1   0   1

数据集2是数据集1的子集,其中1现在表示在调查过程中发现了感兴趣的物种

数据集2:

Block  A1  A2  A4  A5
    1   0   1   0   0
    3   0   0   0   1

理想的输出看起来像这样,其中2表示已执行调查并找到了感兴趣的物种,1表示已进行调查,而0表示未进行调查。

数据集3:

Block A1  A2  A3  A4  A5
  1    0   2   0   0   0
  2    1   0   0   1   0
  3    0   0   1   0   2

3 个答案:

答案 0 :(得分:1)

所以我会比这里的其他人效率低一些:

library(tidyverse)

data1 %>% 
gather(key,value,-Block) %>% 
rbind(data2 %>% 
gather(key,value, -Block)) %>% 
group_by(Block, key) %>% 
summarise(All_vals = sum(value)) %>% 
spread(key, All_vals)

这是结果:

 Block    A1    A2    A3    A4    A5
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1     1     0     2     0     0     0
2     2     1     0     0     1     0
3     3     0     0     1     1     2

答案 1 :(得分:1)

编辑

使用dplyr动词和%>%似乎有点不舒服,所以我决定添加一些其他可能更有吸引力的解决方案。

请注意,如果您的一个或多个变量是非数字的,那么这些解决方案都将无法正常工作,对于您的真实数据来说似乎就是这种情况。您需要找出哪些不是数字,然后将其转换为数字或删除它们。

使用基数R

rbind函数将通过匹配变量(如果它们都具有相同的变量)来连接数据帧。您应该将缺失的变量添加到值NA的数据框中,然后rbind。然后,您可以在合并数据帧的子集上调用aggregate,并按Block的级别求和:

full_df <- rbind(df1, cbind(df2, A3 = NA))
aggregate(full_df[,2:6], list(Block = full_df$Block), sum, na.rm = T)

#### OUTPUT ####

  Block A1 A2 A3 A4 A5
1     1  0  2  0  0  0
2     2  1  0  0  1  0
3     3  0  0  1  0  2

使用dplyr

dplyr函数bind_rows相当灵活,通过匹配共享变量并用NA自动填充不匹配的变量,可以使连接数据帧变得更加容易。按Block分组,然后使用summarise_all将函数应用于每个变量:

library(dplyr)

bind_rows(df1, df2) %>%
    group_by(Block) %>% 
    summarise_all(sum, na.rm = T)

#### OUTPUT ####

# A tibble: 3 x 6
  Block    A1    A2    A3    A4    A5
  <int> <int> <int> <int> <int> <int>
1     1     0     2     0     0     0
2     2     1     0     0     1     0
3     3     0     0     1     0     2

使用data.table

另一种选择是使用data.table,它以快速而著称,并且使用某些人喜欢的不同语法。

library(data.table)

full_df <- rbindlist(list(df1, df2), fill = T)
full_df[, lapply(.SD, sum, na.rm = T), by = "Block"]

#### OUTPUT ####

   Block A1 A2 A3 A4 A5
1:     1  0  2  0  0  0
2:     2  1  0  0  1  0
3:     3  0  0  1  0  2

答案 2 :(得分:0)

使用基数R!

matrix2 <- matrix(rep(0, length.out = nrow(dataset1)*ncol(dataset1)),
ncol = ncol(dataset1))
#then make sure the column names match dataset1 (not dataset2)
names(matrix2) <- names(dataset1)
for (i in 1:ncol(matrix2)) {
if (any(names(dataset2) == names(matrix2)[i]
matrix2[,i] <- dataset2[,which(names(dataset2) == names(matrix2)[i]]
}
}

然后将这些列与数据集1的位置/顺序相同(否则为零)添加到数据集1:

for (i in 1:ncol(dataset1) {dataset1[,i] <- dataset1[,i] + matrix2[,i]}