使用dplyr有条件地替换行中的值

使用dplyr有条件地替换行中的值,r,dplyr,R,Dplyr,我有一个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 var

我有一个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

您的问题使这一点变得不清楚,但是如果您有一些默认值,您总是希望使用这些默认值来替换缺少的值,例如,如果1994是您的基线,那么我建议您首先生成这些默认值:

defaultValues <-
  df %>%
  filter(year == 1994) %>%
  select(groups
         , default_var1 = var1
         , default_var2 = var2)
如果您的默认设置更复杂,您只需要构造它们以匹配您所需的行为。例如,如果希望它填写两年前的值,请使用:

complex_defaultValues <-
  df %>%
  mutate(year = year + 2) %>%
  rename(default_var1 = var1
         , default_var2 = var2)

这将自动填充,因此请确保您的数据按您想要的方式排序

,因为不清楚您希望如何替换缺少的值,我使用均值插补替换它们,取列的平均值,并使用该值替换值

# 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
替换为分别使用dplyr的mutate_的方法


你的意思是有条件的,每一组的var1是否为正?@ColonelBeauvel否,当年份==1996时,var1是否为NA请使用set.seed当使用诸如RNORM之类的函数时,你想用什么替换NA?请注意,我更新了数据-在原始数据中,1994年全部为第4组,91年为第1组,等等。我想用另一行中的值替换缺失的行,例如,如果某个组中1996年的所有值缺失,则用该组1994年的值替换它们
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)
df %>%
  group_by(groups) %>%
  fill(var1, var2)
# 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
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
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