如何用 R 中同一日期不同年份的平均数据替换特定日期的 NA 数据?
How to replace NA data of specific dates with the average data of different years of same dates of a dataframe in R?
如果我有一个数据框A
A =
year month day hour minute rain
.
.
.
2000 01 01 01 00 2
2000 01 01 01 15 2
2000 01 01 01 30 NA
2000 01 01 01 45 3
2000 01 01 02 00 4
2000 01 01 02 15 5
.
.
.
Dataframe A 有 1990 年到 2000 年的数据,频率数据为 15 分钟。
所以 A 具有相同日期和不同年份的特定缺失数据 (NA):
A =
year month day hour minute rain
1990 01 01 01 30 10
.
.
.
1991 01 01 01 30 21
.
.
.
1992 01 01 01 30 4
.
.
.
1993 01 01 01 30 6
.
.
.
1994 01 01 01 30 10
.
.
.
1995 01 01 01 30 23
.
.
.
1996 01 01 01 30 0
.
.
.
1997 01 01 01 30 0
.
.
.
1998 01 01 01 30 0
.
.
.
1999 01 01 01 30 6
.
.
.
2000 01 01 01 30 NA
想法是在 Rain 列中查找每个 NA 数据,并将它们替换为从 1990 年到 2000 年每年同一日期的平均值。
新的 A 将适用于 2000 年:
A =
year month day hour minute rain
.
.
.
2000 01 01 01 00 2
2000 01 01 01 15 2
2000 01 01 01 30 **8**
2000 01 01 01 45 3
2000 01 01 02 00 4
2000 01 01 02 15 5
.
.
.
这可能有用。它将月份和日期对分组,并从平均值中替换 NA
s。
library(dplyr)
A <- A %>%
group_by(month, day, hour, minute) %>%
mutate(rain = ifelse(is.na(rain),
mean(rain, na.rm=TRUE), rain))
使用 dplyr 的解决方案。思路是将A
中的雨按月、日、时、分汇总,按这些列join,然后用平均雨值替换rain
中的NA
。
注意OP更新澄清原问题后,headpoint的回答更加简单明了()。但是,我仍然在这里保留我的答案作为示例,以表明如果替换值来自另一个数据框,则 left_join
方法将很有用。
library(dplyr)
A2 <- A %>%
left_join(A %>%
group_by(month, day, hour, minute) %>%
summarise(mean_rain = mean(rain, na.rm = TRUE)),
by = c("month", "day", "hour", "minute")) %>%
mutate(rain = ifelse(is.na(rain), mean_rain, rain)) %>%
select(-mean_rain)
A2
# year month day hour minute rain
# 1 1990 1 1 1 30 10
# 2 1991 1 1 1 30 21
# 3 1992 1 1 1 30 4
# 4 1993 1 1 1 30 6
# 5 1994 1 1 1 30 10
# 6 1995 1 1 1 30 23
# 7 1996 1 1 1 30 0
# 8 1997 1 1 1 30 0
# 9 1998 1 1 1 30 0
# 10 1999 1 1 1 30 6
# 11 2000 1 1 1 0 2
# 12 2000 1 1 1 15 2
# 13 2000 1 1 1 30 8
# 14 2000 1 1 1 45 3
# 15 2000 1 1 2 0 4
# 16 2000 1 1 2 15 5
数据
A <- read.table(text = "year month day hour minute rain
1990 01 01 01 30 10
1991 01 01 01 30 21
1992 01 01 01 30 4
1993 01 01 01 30 6
1994 01 01 01 30 10
1995 01 01 01 30 23
1996 01 01 01 30 0
1997 01 01 01 30 0
1998 01 01 01 30 0
1999 01 01 01 30 6
2000 01 01 01 00 2
2000 01 01 01 15 2
2000 01 01 01 30 NA
2000 01 01 01 45 3
2000 01 01 02 00 4
2000 01 01 02 15 5",
header = TRUE, stringsAsFactors = FALSE)
这里有一个dplyr
方法,它只使用前几年同一时间的平均值。也就是说,与 headpoint 和 www 提供的解决方案相反,这不会使用 01:30、2001 年 1 月 1 日或 2002 年(等)的值来计算用于 01:30、2000 年 1 月 1 日的平均值,但是而是 2000 年 之前 所有年份的 1 月 1 日 01:30 的平均降雨值。
因此,首先,我们只需重新创建要使用的 A 数据框。我只加载 tibble 包以使用 tribble
函数重新创建您的数据框示例。
library(dplyr)
library(tibble)
A <- tribble(
~ year, ~month, ~day, ~hour, ~minute, ~rain,
1990, 01, 01, 01, 30, 10,
1991, 01, 01, 01, 30, 21,
1992, 01, 01, 01, 30, 4,
1993, 01, 01, 01, 30, 6,
1994, 01, 01, 01, 30, 10,
1995, 01, 01, 01, 30, 23,
1996, 01, 01, 01, 30, 0,
1997, 01, 01, 01, 30, 0,
1998, 01, 01, 01, 30, 0,
2000, 01, 01, 01, 00, 2,
2000, 01, 01, 01, 15, 2,
2000, 01, 01, 01, 30, NA,
2000, 01, 01, 01, 45, 3,
2000, 01, 01, 02, 00, 4,
2000, 01, 01, 02, 15, 5)
然后我们要做的是按月、日、小时和分钟分组,这样我们就可以创建前几年当天那个时间的 运行 平均值。如果下一年有 NA
值,则将使用最近的一个。
A <- A %>%
group_by(month, day, hour, minute) %>%
mutate(running_mean = round(cummean(rain), 0),
most_recent_mean = lag(running_mean),
rain = if_else(is.na(rain), most_recent_mean, rain)) %>%
select(-running_mean, -most_recent_mean)
这应该可以解决问题。打印结果如下:
# A tibble: 15 x 6
# Groups: month, day, hour, minute [6]
year month day hour minute rain
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1990 1 1 1 30 10
2 1991 1 1 1 30 21
3 1992 1 1 1 30 4
4 1993 1 1 1 30 6
5 1994 1 1 1 30 10
6 1995 1 1 1 30 23
7 1996 1 1 1 30 0
8 1997 1 1 1 30 0
9 1998 1 1 1 30 0
10 2000 1 1 1 0 2
11 2000 1 1 1 15 2
12 2000 1 1 1 30 8
13 2000 1 1 1 45 3
14 2000 1 1 2 0 4
15 2000 1 1 2 15 5
您可以通过year
、month
、day
:
将雨柱coalesce
平均(没有NA
)
library(data.table)
library(hutils)
setDT(A)[,
rain := coalesce(rain, mean(rain, na.rm = TRUE)),
keyby = c("year", "month", "day")]
如果您不想安装 hutils
,dplyr
的功能几乎相同,但 hutils::coalesce
更快:
copy(A)[, `:=`(rain2, hutils::coalesce(rain, mean(rain, na.rm = TRUE))), keyby = c("year", "month", "day")]
copy(A)[, `:=`(rain2, dplyr::coalesce(rain, mean(rain, na.rm = TRUE))), keyby = c("year", "month", "day")]
min lq mean median uq max neval cld
107.1927 118.8372 132.8129 121.4076 128.0383 634.658 100 a
887.1115 921.6607 960.4542 943.0711 980.5143 1145.658 100 b
生成示例文件:
A <-
CJ(year = 1990:2000,
month = 1:12,
day = 1:31, # yeah I know not all months have 31 days; doesn't matter here
hour = 0:23,
minute = 15L * c(0:3))
A[, rain := NA_real_]
A[sample.int(nrow(A), size = 0.8 * nrow(A)), rain := rexp(0.8 * nrow(A), rate = 2)]
如果我有一个数据框A
A =
year month day hour minute rain
.
.
.
2000 01 01 01 00 2
2000 01 01 01 15 2
2000 01 01 01 30 NA
2000 01 01 01 45 3
2000 01 01 02 00 4
2000 01 01 02 15 5
.
.
.
Dataframe A 有 1990 年到 2000 年的数据,频率数据为 15 分钟。
所以 A 具有相同日期和不同年份的特定缺失数据 (NA):
A =
year month day hour minute rain
1990 01 01 01 30 10
.
.
.
1991 01 01 01 30 21
.
.
.
1992 01 01 01 30 4
.
.
.
1993 01 01 01 30 6
.
.
.
1994 01 01 01 30 10
.
.
.
1995 01 01 01 30 23
.
.
.
1996 01 01 01 30 0
.
.
.
1997 01 01 01 30 0
.
.
.
1998 01 01 01 30 0
.
.
.
1999 01 01 01 30 6
.
.
.
2000 01 01 01 30 NA
想法是在 Rain 列中查找每个 NA 数据,并将它们替换为从 1990 年到 2000 年每年同一日期的平均值。
新的 A 将适用于 2000 年:
A =
year month day hour minute rain
.
.
.
2000 01 01 01 00 2
2000 01 01 01 15 2
2000 01 01 01 30 **8**
2000 01 01 01 45 3
2000 01 01 02 00 4
2000 01 01 02 15 5
.
.
.
这可能有用。它将月份和日期对分组,并从平均值中替换 NA
s。
library(dplyr)
A <- A %>%
group_by(month, day, hour, minute) %>%
mutate(rain = ifelse(is.na(rain),
mean(rain, na.rm=TRUE), rain))
使用 dplyr 的解决方案。思路是将A
中的雨按月、日、时、分汇总,按这些列join,然后用平均雨值替换rain
中的NA
。
注意OP更新澄清原问题后,headpoint的回答更加简单明了(left_join
方法将很有用。
library(dplyr)
A2 <- A %>%
left_join(A %>%
group_by(month, day, hour, minute) %>%
summarise(mean_rain = mean(rain, na.rm = TRUE)),
by = c("month", "day", "hour", "minute")) %>%
mutate(rain = ifelse(is.na(rain), mean_rain, rain)) %>%
select(-mean_rain)
A2
# year month day hour minute rain
# 1 1990 1 1 1 30 10
# 2 1991 1 1 1 30 21
# 3 1992 1 1 1 30 4
# 4 1993 1 1 1 30 6
# 5 1994 1 1 1 30 10
# 6 1995 1 1 1 30 23
# 7 1996 1 1 1 30 0
# 8 1997 1 1 1 30 0
# 9 1998 1 1 1 30 0
# 10 1999 1 1 1 30 6
# 11 2000 1 1 1 0 2
# 12 2000 1 1 1 15 2
# 13 2000 1 1 1 30 8
# 14 2000 1 1 1 45 3
# 15 2000 1 1 2 0 4
# 16 2000 1 1 2 15 5
数据
A <- read.table(text = "year month day hour minute rain
1990 01 01 01 30 10
1991 01 01 01 30 21
1992 01 01 01 30 4
1993 01 01 01 30 6
1994 01 01 01 30 10
1995 01 01 01 30 23
1996 01 01 01 30 0
1997 01 01 01 30 0
1998 01 01 01 30 0
1999 01 01 01 30 6
2000 01 01 01 00 2
2000 01 01 01 15 2
2000 01 01 01 30 NA
2000 01 01 01 45 3
2000 01 01 02 00 4
2000 01 01 02 15 5",
header = TRUE, stringsAsFactors = FALSE)
这里有一个dplyr
方法,它只使用前几年同一时间的平均值。也就是说,与 headpoint 和 www 提供的解决方案相反,这不会使用 01:30、2001 年 1 月 1 日或 2002 年(等)的值来计算用于 01:30、2000 年 1 月 1 日的平均值,但是而是 2000 年 之前 所有年份的 1 月 1 日 01:30 的平均降雨值。
因此,首先,我们只需重新创建要使用的 A 数据框。我只加载 tibble 包以使用 tribble
函数重新创建您的数据框示例。
library(dplyr)
library(tibble)
A <- tribble(
~ year, ~month, ~day, ~hour, ~minute, ~rain,
1990, 01, 01, 01, 30, 10,
1991, 01, 01, 01, 30, 21,
1992, 01, 01, 01, 30, 4,
1993, 01, 01, 01, 30, 6,
1994, 01, 01, 01, 30, 10,
1995, 01, 01, 01, 30, 23,
1996, 01, 01, 01, 30, 0,
1997, 01, 01, 01, 30, 0,
1998, 01, 01, 01, 30, 0,
2000, 01, 01, 01, 00, 2,
2000, 01, 01, 01, 15, 2,
2000, 01, 01, 01, 30, NA,
2000, 01, 01, 01, 45, 3,
2000, 01, 01, 02, 00, 4,
2000, 01, 01, 02, 15, 5)
然后我们要做的是按月、日、小时和分钟分组,这样我们就可以创建前几年当天那个时间的 运行 平均值。如果下一年有 NA
值,则将使用最近的一个。
A <- A %>%
group_by(month, day, hour, minute) %>%
mutate(running_mean = round(cummean(rain), 0),
most_recent_mean = lag(running_mean),
rain = if_else(is.na(rain), most_recent_mean, rain)) %>%
select(-running_mean, -most_recent_mean)
这应该可以解决问题。打印结果如下:
# A tibble: 15 x 6
# Groups: month, day, hour, minute [6]
year month day hour minute rain
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1990 1 1 1 30 10
2 1991 1 1 1 30 21
3 1992 1 1 1 30 4
4 1993 1 1 1 30 6
5 1994 1 1 1 30 10
6 1995 1 1 1 30 23
7 1996 1 1 1 30 0
8 1997 1 1 1 30 0
9 1998 1 1 1 30 0
10 2000 1 1 1 0 2
11 2000 1 1 1 15 2
12 2000 1 1 1 30 8
13 2000 1 1 1 45 3
14 2000 1 1 2 0 4
15 2000 1 1 2 15 5
您可以通过year
、month
、day
:
coalesce
平均(没有NA
)
library(data.table)
library(hutils)
setDT(A)[,
rain := coalesce(rain, mean(rain, na.rm = TRUE)),
keyby = c("year", "month", "day")]
如果您不想安装 hutils
,dplyr
的功能几乎相同,但 hutils::coalesce
更快:
copy(A)[, `:=`(rain2, hutils::coalesce(rain, mean(rain, na.rm = TRUE))), keyby = c("year", "month", "day")]
copy(A)[, `:=`(rain2, dplyr::coalesce(rain, mean(rain, na.rm = TRUE))), keyby = c("year", "month", "day")]
min lq mean median uq max neval cld
107.1927 118.8372 132.8129 121.4076 128.0383 634.658 100 a
887.1115 921.6607 960.4542 943.0711 980.5143 1145.658 100 b
生成示例文件:
A <-
CJ(year = 1990:2000,
month = 1:12,
day = 1:31, # yeah I know not all months have 31 days; doesn't matter here
hour = 0:23,
minute = 15L * c(0:3))
A[, rain := NA_real_]
A[sample.int(nrow(A), size = 0.8 * nrow(A)), rain := rexp(0.8 * nrow(A), rate = 2)]