关于r:用另一个df的值替换na

Replace na's with value from another df

我在下面有两个数据框,第一个df记录了约15k条按时间和日期记录的步数,第二个df是每个间隔时间的平均步数。我想做的是遍历df1并将na值替换为df2的avg.steps值,但是我似乎无法弄清楚R。这是最有效的方法做这个?有没有办法使用dplyr做到这一点?

df1看起来像这样:

1
2
3
4
5
6
7
8
9
10
steps <- c(51, 516, NA, NA, 161, 7)
interval <- c(915, 920, 925, 930, 935, 940)

steps  interval
   51       915
  516       920
   NA       925
   NA       930
  161       935
    7       940

df2看起来像这样:

1
2
3
4
5
6
7
8
9
10
avg.steps <- c(51, 516, 245, 0, 161, 7)
interval <- c(915, 920, 925, 930, 935, 940)

avg.steps  interval
       51       915
      516       920
      245       925
        0       930
      161       935
        7       940

这是我使用data.table v1.9.6进行操作的方式:

1
2
require(data.table) # v1.9.6+, for 'on=' feature
dt1[is.na(steps), steps := dt2[.SD, avg.steps, on="interval"]]

第一个参数i = is.na(steps)允许我们仅查看dt1$stepsNA的那些行。在这些行上,我们更新dt1$steps。这是通过执行联接作为子集来完成的。 .SD指数据的子集,即dt1$steps等于NA的那些行。

对于stepsNA的每一行,我们在加入"间隔"列时在dt2中找到相应的匹配行。

作为示例,is.na(steps)将返回dt1中的第三行作为其中的一行。用dt2$interval查找.SD$interval = 925的匹配行将返回索引" 3"(dt2中的第三行)。相应的avg.steps值为" 245"。因此,dt1的第三行将用245

更新。

希望这会有所帮助。

如果dt2的任何dt1$interval值都具有多个匹配项,则必须决定更新哪个值。但是我猜这里不是这样。


只要条目是对应的,就很简单了
df1$steps[is.na(df1$steps)] <- df2$avg.steps[is.na(df1$steps)]

编辑:
如果它们不对应,那么这是dplyr解决方案:

library(dplyr)

1
2
3
df1$steps[is.na(steps)] <- (df1 %>% filter(is.na(steps)) %>%
    group_by(interval) %>%
    mutate(steps = rep(df2$avg.steps[df2$interval == interval[1]], length(interval)))$steps