我有一个data.frame,其变量按组和年份编制索引,如下所示:
library(tidyverse)
set.seed(8675309)
df <- data.frame(
year = rep(1991:2000, 10),
groups = rep(1:10, each = 10),
var1 = rnorm(100),
var2 = rnorm(100)
)
head(df)
year groups var1 var2
1 1991 1 -0.9965824 0.74453768
2 1992 1 0.7218241 -1.34662801
3 1993 1 -0.6172088 0.33014251
4 1994 1 2.0293916 -0.01272533
5 1995 1 1.0654161 -0.46367596
6 1996 1 0.9872197 0.20494209
某些特定年份缺少某些观察结果,比如1996年:
df[df$year == 1996, ]$var1 <- ifelse(df[df$year == 1996, ]$var1 > 0,
NA, df[df$year == 1996, ]$var1)
## If 1996 is missing in var1, it is missing in all vars:
df$var2 <- ifelse(is.na(df$var1), NA, df$var2)
我的问题是,如何替换var1
和var2
的值取决于它们是否已存在?这是我想要的要点:
df %>%
group_by(groups) %>%
mutate_all(funs(replace_1996_if_NA_with_value_from_1994))
答案 0 :(得分:1)
你的问题不清楚,但如果你有一些默认值,你总是想用来替换缺失的值(例如,如果1994是你的基线),那么我建议你先生成这些默认值:
defaultValues <-
df %>%
filter(year == 1994) %>%
select(groups
, default_var1 = var1
, default_var2 = var2)
然后,使用left_join
合并组。这样,每一行现在也将具有默认值。然后,您可以使用coalesce
选择第一个非NA值 - 当且仅当缺少该值时,这将是默认值。最后清除默认值。
df %>%
left_join(defaultValues) %>%
mutate(var1 = coalesce(var1, default_var1)
, var2 = coalesce(var2, default_var2)) %>%
select(-starts_with("default"))
如果您的默认值更复杂,您只需构建它们以匹配您想要的行为即可。例如,如果您希望它填写两年前的值,请使用:
complex_defaultValues <-
df %>%
mutate(year = year + 2) %>%
rename(default_var1 = var1
, default_var2 = var2)
然后,加入年份和小组,它将正确对齐(但请注意,如果两年前的值丢失,在coalesce
之后仍然会丢失。所以,您可能需要帐户对于默认值中的缺失。)
最后,如果您只想向前传播最后一个非NA值(而不是尝试返回两年,或者始终使用相同的默认值),则可以使用fill
中的tidyr
:
df %>%
group_by(groups) %>%
fill(var1, var2)
会自动填写(因此请确保您的数据按照您想要的方式排序)
答案 1 :(得分:0)
由于您不清楚如何更换缺失值,我会使用均值插补替换它们(取列的平均值并使用它来替换值)。
# Some of the observations are now missing
n <- 10
df[cbind(sample(1:nrow(df), n, replace=T), sample(1:ncol(df), n, replace=T))] <- NA
我们提取包含NA
&#39;
df[rowSums(is.na(df)) > 0,]
# year groups var1 var2
# 5 1995 1 NA -0.4636760
# 14 1994 2 NA 1.1556394
# 34 1994 NA 0.58852729 -0.7053416
# 37 1997 4 0.06391704 NA
# 47 1997 NA -0.87493144 1.1691501
# 50 2000 5 0.03609091 NA
# 54 1994 NA -2.13523626 -1.0991012
# 80 2000 8 -1.35752606 NA
# 84 NA 9 0.02038586 -1.6054171
# 92 1992 NA 0.59155773 -1.768570
使用dplyr
&#39; s mutate_each()
newDF <- mutate_each(df, funs(ifelse(is.na(.), mean(., na.rm=T), .)))
更新了专栏:
newDF[rowSums(is.na(df)) > 0,]
year groups var1 var2
# 5 1995.000 1.00000 0.04923291 -0.46367596
# 14 1994.000 2.00000 0.04923291 1.15563940
# 34 1994.000 5.46875 0.58852729 -0.70534164
# 37 1997.000 4.00000 0.06391704 -0.04406217
# 47 1997.000 5.46875 -0.87493144 1.16915008
# 50 2000.000 5.00000 0.03609091 -0.04406217
# 54 1994.000 5.46875 -2.13523626 -1.09910122
# 80 2000.000 8.00000 -1.35752606 -0.04406217
# 84 1995.515 9.00000 0.02038586 -1.60541710
# 92 1992.000 5.46875 0.59155773 -1.76857084