首页 > 解决方案 > 如何使用 dplyr 根据另一个数据框填充数据框中的列

问题描述

我有两个数据框,我正在尝试使用第一个数据框的列中的值替换第二个数据框的列中的 NA。我想使用这个dplyr包来做这个,我不熟悉这个包:

这是一个可重现的示例:

library(dplyr)
## Create the two data frames
      dt1 <- data.frame(ID = c(rep(1, 6), rep(2, 6), rep(3, 6)), day = c(seq(0, 5, by= 1), seq(0, 5, by= 1), seq(0, 5, by= 1)), density = sample(1:100, 6*3))
      dt2 <- data.frame(ID = c(rep(1, 6), rep(2, 6), rep(3, 6)), day = c(seq(0, 5, by= 1), seq(0, 5, by= 1), seq(0, 5, by= 1)), density = NA)

## Fill the second data frame
     dt2[dt2$day == 0, c("density")] <- c(1, 2, 8)
     dt2[dt2$day %in% c(1, 2, 3, 4, 5), c("density")] <- dt1[dt1$day %in% c(0, 1, 2, 3, 4), c("density")] 
## the values in the column "ID" of dt1 must be equivalent to the values in the column "ID" of dt2

如何使用dplyr包重现最后两个命令?

这是我的测试:

  dt2_fill <- dt2 %>% 
    mutate(density = if(day == 0){c(1, 2, 8)},
           density = if(day %in% c(1, 2, 3, 4, 5)){dt1[dt1$day %in% c(0, 1, 2, 3, 4), c("density")]})

但是这段代码不起作用。

标签: rdplyr

解决方案


这可能不是一个理想的解决方案,但给出了预期的输出

完整的dplyr解决方案

library(dplyr)
dt2 %>%
  filter(day == 0) %>%
  mutate(density = c(1, 2, 8)) %>%
  bind_rows(dt2 %>%
              filter(day %in% c(1, 2, 3, 4, 5)) %>%
              mutate(density = dt1 %>%
                              filter(day %in% c(0, 1, 2, 3, 4)) %>% 
                               pull(density)
             ))

#   ID day density
#1   1   0       1
#2   2   0       2
#3   3   0       8
#4   1   1      84
#5   1   2      72
#6   1   3       4
#7   1   4      31
#....

我们首先filter将行day == 0分配c(1, 2, 8)给它们。对于剩余的行,我们从 中获取相应的densitydt1


我们可以通过以下方式减少一点复杂性

dt2 %>%
   filter(day == 0) %>%
   mutate(density = c(1, 2, 8)) %>%
   bind_rows(dt2 %>%
              filter(day %in% c(1, 2, 3, 4, 5)) %>%
              mutate(density = dt1$density[dt1$day %in% c(0, 1, 2, 3, 4)])
          )

推荐阅读