我有两个数据帧,我试图使用第一个数据帧的列中的值替换第二个数据帧的列中的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")]})
但是此代码不起作用。
答案 0 :(得分:2)
这可能不是理想的解决方案,但可以提供预期的输出
完整的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)
。对于其余的行,我们从density
中获得相应的dt1
列。
我们可以通过以下方式降低复杂性
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)])
)
答案 1 :(得分:2)
您似乎在这里尝试做的事情,至少在实践中,是合并两个数据帧。您的ID
和day
变量用作唯一标识符,除了dt1中的day
变量在dt2中偏移了一个。那么这样的解决方案呢?
dt2 <- dt1 %>%
mutate(day = day + 1) %>% # Adjust "day" variable to line up with the "day" variable in dt2
right_join(dt2 %>% select(-density), by = c("ID", "day"))
在day == 0
的情况下,NA将保留在密度变量中。您可以使用Ronak上面建议的过滤器/绑定行解决方案解决该问题,也可以使用ifelse
语句来分配这些情况,如下所示:
dt2 <- dt2 %>%
mutate(density = ifelse(day > 0, density,
ifelse(ID == 1, 1,
ifelse(ID == 2, 2, 8))))
(这有点麻烦,我想如果您想提供更多详细信息,在您的实际案例中可能会有更好的解决方案。)
另一种选择就是直接从dt1创建dt2数据帧:
dt2 <- dt1 %>%
mutate(day = day + 1) %>%
filter(day < 6) %>%
bind_rows(tibble(ID = c(1,2,3), day = 0, density = c(1,2,8))) %>%
arrange(ID, day)