如何按组均值替换 NA?
How to replace NAs by group mean?
我有两个数据框,一个包含原始数据(和大量 NA),另一个包含不同时间间隔的原始数据的均值。
我想在这些时间间隔内用平均值替换 NA,同时保留非 NA。
我在 "impute missing data r" 或 "replace missing data r" 上搜索了很多,但还没有找到任何似乎合适的解决方案,它们似乎都用 0:s 替换数据,或使用复杂的方法来完成此任务,例如使用 MICE 包。
代码示例:
这是第一个 DF 的头部,带有原始数据。正如你所看到的,第一天他们都是NA。
steps date interval
1 NA 2012-10-01 0
2 NA 2012-10-01 5
3 NA 2012-10-01 10
4 NA 2012-10-01 15
5 NA 2012-10-01 20
6 NA 2012-10-01 25
...
第二个数据帧头包含每个间隔的平均步数,如下所示:
steps interval
1 1.72 0
2 0.340 5
3 0.132 10
4 0.151 15
5 0.0755 20
6 2.09 25
...
现在,我正在寻找的是能够用相关间隔的平均步长填充 NA,所以它看起来像这样:
steps date interval
1 1.72 2012-10-01 0
2 0.340 2012-10-01 5
3 0.132 2012-10-01 10
4 0.151 2012-10-01 15
5 0.0755 2012-10-01 20
6 2.09 2012-10-01 25
...
我错过了任何提示或资源链接吗?由于这是一项课程作业,我主要想学习,如果没有为我完成作业而提供任何帮助,将不胜感激! =)
编辑:此外,由于这是我在 Stack Overflow 上提出的第一个问题,任何关于如何改进我的问题制作的评论也非常感谢!
在 R 中有很多方法可以做到这一点。例如
# generate dataframe with some interval vaulues
df1 <- data.frame(interval= rep(seq(0, 25, 5), 5))
# add a steps column
df1$steps <- 1:nrow(df)
# copy the dataframe
df2 <- df1
# replace some steps values with missings in df1
df1$steps[c(1,2,5, 14)] <- NA
# sapply goes thru every unique interval...
sapply(df1$interval, function(interval_i){
# replace missing steps of interval_i in df1 with the steps mean of interval_i of df2
df1$steps[is.na(df1$steps) & df1$interval == interval_i] <<- mean(df2$steps[df2$interval == interval_i], na.rm= TRUE)
# you must use <<- not <- to assign it to df outside of sapply
})
我将使用 dplyr
添加解决方案。
最好在问题中提供一些可重现的数据,而不是直接将其放入 R 中,而不仅仅是粘贴到数据的头部。我创建了一些虚拟数据:
# create random sample data
library(dplyr)
set.seed(100)
df1 <- tibble(
steps = runif(1e3),
date = lubridate::today() + runif(1e3) * 24,
interval = as.numeric(sample(seq(0,25, by=5), 1e3, replace = T))
)
# add 100 NAs at random
df1$steps[sample(1:1e3, 100)] <- NA
df1
# steps date interval
# <dbl> <date> <dbl>
# 1 0.308 2019-07-18 15
# 2 NA 2019-07-19 10
# 3 NA 2019-07-31 0
# 4 0.0564 2019-08-02 20
# 5 0.469 2019-07-25 0
# 6 0.484 2019-07-21 25
# 7 NA 2019-07-17 5
# 8 0.370 2019-07-28 0
# 9 0.547 2019-07-31 5
# 10 0.170 2019-08-08 15
# # … with 990 more rows
使用 dplyr
插补任务就非常简单 group_by
df1 %>%
group_by(interval) %>%
mutate(steps = if_else(is.na(steps), mean(steps, na.rm = T), steps))
# # A tibble: 1,000 x 3
# # Groups: interval [6]
# steps date interval
# <dbl> <date> <dbl>
# 1 0.308 2019-07-18 15
# 2 0.573 2019-07-19 10
# 3 0.523 2019-07-31 0
# 4 0.0564 2019-08-02 20
# 5 0.469 2019-07-25 0
# 6 0.484 2019-07-21 25
# 7 0.527 2019-07-17 5
# 8 0.370 2019-07-28 0
# 9 0.547 2019-07-31 5
# 10 0.170 2019-08-08 15
# # … with 990 more rows
我们可以通过计算每组的均值并将其与估算值进行比较来确认每组的估算均值是正确的:
df1 %>%
group_by(interval) %>%
summarise(mean_int = mean(steps, na.rm=T))
# # A tibble: 6 x 2
# interval mean_int
# <dbl> <dbl>
# 1 0 0.523
# 2 5 0.527
# 3 10 0.573
# 4 15 0.511
# 5 20 0.475
# 6 25 0.485
我有两个数据框,一个包含原始数据(和大量 NA),另一个包含不同时间间隔的原始数据的均值。
我想在这些时间间隔内用平均值替换 NA,同时保留非 NA。
我在 "impute missing data r" 或 "replace missing data r" 上搜索了很多,但还没有找到任何似乎合适的解决方案,它们似乎都用 0:s 替换数据,或使用复杂的方法来完成此任务,例如使用 MICE 包。
代码示例: 这是第一个 DF 的头部,带有原始数据。正如你所看到的,第一天他们都是NA。
steps date interval
1 NA 2012-10-01 0
2 NA 2012-10-01 5
3 NA 2012-10-01 10
4 NA 2012-10-01 15
5 NA 2012-10-01 20
6 NA 2012-10-01 25
...
第二个数据帧头包含每个间隔的平均步数,如下所示:
steps interval
1 1.72 0
2 0.340 5
3 0.132 10
4 0.151 15
5 0.0755 20
6 2.09 25
...
现在,我正在寻找的是能够用相关间隔的平均步长填充 NA,所以它看起来像这样:
steps date interval
1 1.72 2012-10-01 0
2 0.340 2012-10-01 5
3 0.132 2012-10-01 10
4 0.151 2012-10-01 15
5 0.0755 2012-10-01 20
6 2.09 2012-10-01 25
...
我错过了任何提示或资源链接吗?由于这是一项课程作业,我主要想学习,如果没有为我完成作业而提供任何帮助,将不胜感激! =)
编辑:此外,由于这是我在 Stack Overflow 上提出的第一个问题,任何关于如何改进我的问题制作的评论也非常感谢!
在 R 中有很多方法可以做到这一点。例如
# generate dataframe with some interval vaulues
df1 <- data.frame(interval= rep(seq(0, 25, 5), 5))
# add a steps column
df1$steps <- 1:nrow(df)
# copy the dataframe
df2 <- df1
# replace some steps values with missings in df1
df1$steps[c(1,2,5, 14)] <- NA
# sapply goes thru every unique interval...
sapply(df1$interval, function(interval_i){
# replace missing steps of interval_i in df1 with the steps mean of interval_i of df2
df1$steps[is.na(df1$steps) & df1$interval == interval_i] <<- mean(df2$steps[df2$interval == interval_i], na.rm= TRUE)
# you must use <<- not <- to assign it to df outside of sapply
})
我将使用 dplyr
添加解决方案。
最好在问题中提供一些可重现的数据,而不是直接将其放入 R 中,而不仅仅是粘贴到数据的头部。我创建了一些虚拟数据:
# create random sample data
library(dplyr)
set.seed(100)
df1 <- tibble(
steps = runif(1e3),
date = lubridate::today() + runif(1e3) * 24,
interval = as.numeric(sample(seq(0,25, by=5), 1e3, replace = T))
)
# add 100 NAs at random
df1$steps[sample(1:1e3, 100)] <- NA
df1
# steps date interval
# <dbl> <date> <dbl>
# 1 0.308 2019-07-18 15
# 2 NA 2019-07-19 10
# 3 NA 2019-07-31 0
# 4 0.0564 2019-08-02 20
# 5 0.469 2019-07-25 0
# 6 0.484 2019-07-21 25
# 7 NA 2019-07-17 5
# 8 0.370 2019-07-28 0
# 9 0.547 2019-07-31 5
# 10 0.170 2019-08-08 15
# # … with 990 more rows
使用 dplyr
插补任务就非常简单 group_by
df1 %>%
group_by(interval) %>%
mutate(steps = if_else(is.na(steps), mean(steps, na.rm = T), steps))
# # A tibble: 1,000 x 3
# # Groups: interval [6]
# steps date interval
# <dbl> <date> <dbl>
# 1 0.308 2019-07-18 15
# 2 0.573 2019-07-19 10
# 3 0.523 2019-07-31 0
# 4 0.0564 2019-08-02 20
# 5 0.469 2019-07-25 0
# 6 0.484 2019-07-21 25
# 7 0.527 2019-07-17 5
# 8 0.370 2019-07-28 0
# 9 0.547 2019-07-31 5
# 10 0.170 2019-08-08 15
# # … with 990 more rows
我们可以通过计算每组的均值并将其与估算值进行比较来确认每组的估算均值是正确的:
df1 %>%
group_by(interval) %>%
summarise(mean_int = mean(steps, na.rm=T))
# # A tibble: 6 x 2
# interval mean_int
# <dbl> <dbl>
# 1 0 0.523
# 2 5 0.527
# 3 10 0.573
# 4 15 0.511
# 5 20 0.475
# 6 25 0.485