使用来自两个数据帧的数据进行条件变异

时间:2017-08-24 08:58:40

标签: r dataframe

我有两个数据帧,其中第一个包含数据帧2中某些数据行的新值(数据帧2的数据比没有数据的数据多得多)。 我之前使用以下代码根据另一列中的数字覆盖(从数据帧1到数据帧2)特定列值:

for(i in 1:nrow(Dataset1)){
  sak.i <- Dataset1$column1[i]
  rad.i <- which(Dataset2$column1 == sak.i)
  Dataset2$column2[rad.i] <- Dataset1$column2[i]
  Dataset2$column3[rad.i] <- Dataset1$column3[i]
  ...
  }

这很好用。但是,现在我希望它不会覆盖,而是使用此信息创建一个新列。如果rad.i = TRUE,我希望它为该列插入新值,否则只使用第二个数据帧中已存在的值。所以我想出了这个:

for(i in 1:nrow(Dataset1)){
  sak.i <- Dataset1$column1[i]
  rad.i <- which(Dataset2$column1 == sak.i)
  mutate(new_column_name = ifelse(
    Dataset2$column2[rad.i], Dataset1$column2[i], Dataset2$column2)
         )
  mutate(new_column_name2 = ifelse(
    Dataset2$column3[rad.i], Dataset1$column3[i], Dataset2$column3)
         )
  ...
}

当我运行时,我收到以下错误:

Error in mutate_(.data, .dots = compat_as_lazy_dots(...)) : 
  argument ".data" is missing, with no default

我已经阅读了一些有关错误的内容,但似乎无法隔离问题。

注意:我希望这适用于大约10列。有没有更简单的方法来做到这一点?我是否必须为每列执行mutate命令?

示例:

col11 <- as.character(4:7)
col21 <- c(0.03, 0.06, 1, 2)
col12 <- as.character(1:7)
col22 <- c(67,23,0.03,1,2,10,16)

dataframe1 <- cbind(col11, col21)
dataframe2 <- cbind(col12, col22)

Data frame 1:
col1 col2
4    0.03
5    0.06
6    1
7    2

Data frame 2:
col1  col2
1     67
2     23
3     0.03
4     1
5     2
6     10
7     16

Expected output:
col1  col2  col3
1     67    67
2     23    23
3     0.03  0.03
4     1     0.03
5     2     0.06
6     10    1
7     16    2

1 个答案:

答案 0 :(得分:0)

您可以分两步完成此操作。首先合并col1,然后替换NA,即

final_d <- merge(d1, d2, by = 'col1', all = TRUE)
final_d$col2.x[is.na(final_d$col2.x)] <- final_d$col2.y[is.na(final_d$col2.x)]

给出,

 col1 col2.x col2.y
1    1  67.00  67.00
2    2  23.00  23.00
3    3   0.03   0.03
4    4   0.03   1.00
5    5   0.06   2.00
6    6   1.00  10.00
7    7   2.00  16.00

由于您提及mutate,上述dplyr版本将为

d1 %>% 
 full_join(d2, by = 'col1') %>% 
 mutate(col2.x = replace(col2.x, is.na(col2.x), col2.y[is.na(col2.x)])) %>% 
 arrange(col1)

数据

dput(d1)
structure(list(col1 = 4:7, col2 = c(0.03, 0.06, 1, 2)), .Names = c("col1", 
"col2"), class = "data.frame", row.names = c(NA, -4L))

dput(d2)
structure(list(col1 = 1:7, col2 = c(67, 23, 0.03, 1, 2, 10, 16
)), .Names = c("col1", "col2"), class = "data.frame", row.names = c(NA, 
-7L))