当有 NA 时进行插值
Interpolating when there's NA's
我将纵向数据结构化(在 R 中)如下:
dat1 <- data.frame(county = c("a","a","a", "b","b","b", "c","c","c"), year = c(2001, 2002, 2003, 2001, 2002, 2003, 2001, 2002, 2003), count = c(2, NA, 6, 4, NA, 8, 10, NA, 14))
我有一个缺失的年份,我想插入 2002。我做了一个函数来做:
dat1[dat1$year == 2002,] <- apply(X = data.frame("2001" = dat1[dat1$year == 2001, "count"], "2003" = dat1[dat1$year == 2003, "count"]), MARGIN = 1, FUN = function(x){z <- data.frame(approx(x = x, method = "linear", n = length(2001:2003))$y); return(z[-c(1, nrow(z)),])})
dat1 # the desired result
但只有在我用来插值的两年内没有任何 NA
时才有效:
dat2 <- dat1
dat2[9,3] <- NA
apply(X = data.frame("2001" = dat2[dat2$year == 2001, "count"], "2003" = dat2[dat2$year == 2003, "count"]), MARGIN = 1, FUN = function(x){z <- data.frame(approx(x = x, method = "linear", n = length(2001:2003))$y); return(z[-c(1, nrow(z)),])})
我知道我可以只使用 complete.cases()
使它成为 运行 但是我不能将它插入回原始数据框中,因为行长度会不同。
有没有人能解决我的 NA
前几年或后几年的问题,或者有更好的解决方案来解决我的 kludge-tastic 尝试?
Return NA 如果只有 NA,如果只有一个非 NA,则使用 na.aggregate
将每个 NA 替换为单个非 NA,如果有,则使用 na.approx
一个县不止一个 NA。
library(zoo)
na_approx <- function(x) {
if (all(is.na(x))) NA
else if (sum(!is.na(x)) == 1) na.aggregate(x)
else na.approx(x, na.rm = FALSE)
}
transform(dat2, count = ave(count, county, FUN = na_approx))
给予:
county year count
1 a 2001 2
2 a 2002 4
3 a 2003 6
4 b 2001 4
5 b 2002 6
6 b 2003 8
7 c 2001 10
8 c 2002 10
9 c 2003 10
这是一个替代方案,虽然在本例中给出的结果相同,但其行为可能略有不同。
na_approx2 <- function(x) {
if (sum(!is.na(x)) > 1) na.approx(x, na.rm = FALSE)
else na.locf(x, na.rm = FALSE)
}
transform(dat2, count = ave(count, county, FUN = na_approx2))
我将纵向数据结构化(在 R 中)如下:
dat1 <- data.frame(county = c("a","a","a", "b","b","b", "c","c","c"), year = c(2001, 2002, 2003, 2001, 2002, 2003, 2001, 2002, 2003), count = c(2, NA, 6, 4, NA, 8, 10, NA, 14))
我有一个缺失的年份,我想插入 2002。我做了一个函数来做:
dat1[dat1$year == 2002,] <- apply(X = data.frame("2001" = dat1[dat1$year == 2001, "count"], "2003" = dat1[dat1$year == 2003, "count"]), MARGIN = 1, FUN = function(x){z <- data.frame(approx(x = x, method = "linear", n = length(2001:2003))$y); return(z[-c(1, nrow(z)),])})
dat1 # the desired result
但只有在我用来插值的两年内没有任何 NA
时才有效:
dat2 <- dat1
dat2[9,3] <- NA
apply(X = data.frame("2001" = dat2[dat2$year == 2001, "count"], "2003" = dat2[dat2$year == 2003, "count"]), MARGIN = 1, FUN = function(x){z <- data.frame(approx(x = x, method = "linear", n = length(2001:2003))$y); return(z[-c(1, nrow(z)),])})
我知道我可以只使用 complete.cases()
使它成为 运行 但是我不能将它插入回原始数据框中,因为行长度会不同。
有没有人能解决我的 NA
前几年或后几年的问题,或者有更好的解决方案来解决我的 kludge-tastic 尝试?
Return NA 如果只有 NA,如果只有一个非 NA,则使用 na.aggregate
将每个 NA 替换为单个非 NA,如果有,则使用 na.approx
一个县不止一个 NA。
library(zoo)
na_approx <- function(x) {
if (all(is.na(x))) NA
else if (sum(!is.na(x)) == 1) na.aggregate(x)
else na.approx(x, na.rm = FALSE)
}
transform(dat2, count = ave(count, county, FUN = na_approx))
给予:
county year count
1 a 2001 2
2 a 2002 4
3 a 2003 6
4 b 2001 4
5 b 2002 6
6 b 2003 8
7 c 2001 10
8 c 2002 10
9 c 2003 10
这是一个替代方案,虽然在本例中给出的结果相同,但其行为可能略有不同。
na_approx2 <- function(x) {
if (sum(!is.na(x)) > 1) na.approx(x, na.rm = FALSE)
else na.locf(x, na.rm = FALSE)
}
transform(dat2, count = ave(count, county, FUN = na_approx2))