【问题标题】:Conditional mutate with data from two data frames使用来自两个数据帧的数据进行条件变异
【发布时间】:2017-08-24 08:58:40
【问题描述】:

我有两个数据框,其中第一个包含数据框 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

【问题讨论】:

  • 请展示一个可重现的小例子和预期的输出
  • mutate 需要知道数据框的名称作为其第一个参数 - 请参阅 ?mutate
  • 从 dlpyr 包中变异的工作方式如下:data.frame %>% mutate()。您必须首先指定要变异的数据框。
  • 添加了一个小例子。我现在在前面添加了Dataframe %>%,错误被另一个替换:“mutate_impl(.data, dots) 中的错误:列col3必须是长度4924(行数)或一个,而不是0 "

标签: r dataframe


【解决方案1】:

您可以分两步完成此操作。先在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))

【讨论】:

  • 这会在数据框中创建两个新列吗?我在我的数据上尝试了 dplyr 变体,但我只收到 col2.y 的错误“找不到对象”。我意识到这可以分两步完成,我首先将相关列中的所有信息复制到新列中,然后用来自其他数据帧的数据覆盖新列中的每个特定观察。
  • 我误解了你的意思。我没有意识到 full_join 命令创建了名为 col.x 和 col.y 的列!我猜想组合值存储在 col.x 中?因为 col.y 只包含新值,其余的为 NA
猜你喜欢
  • 2018-02-04
  • 1970-01-01
  • 1970-01-01
  • 2019-12-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-17
  • 2013-07-13
  • 1970-01-01
相关资源
最近更新 更多