将不同列中子组的 NA 值替换为单独列中的其他值

Replace NA values of subgroups in different columns with other values in separate column

我的问题:

Tom_dog <- c(1,4,NA,6,10,5)
Joe_dog <- c(2,NA,8,10,12,5)
Theo_dog <- c(5,1,6,8,NA,7)
Gus_cat <- c(9,10,14,12,13,NA)
Walz_cat <- c(NA, 9,8,7,4,2)
Ron_cat <- c(15,13,NA,2,5,6)
df <- data.frame(Tom_dog,Joe_dog,Theo_dog,Gus_cat,Walz_cat,Ron_cat)

我计算狗和猫的平均值并将其附加到新列中的数据框

df$dog_mean <- rowMeans(df[ , grepl("^.+(_dog)$", colnames(df))], na.rm = TRUE)
df$cat_mean <- rowMeans(df[ , grepl("^.+(_cat)$", colnames(df))], na.rm = TRUE)

现在,我想做的是将狗的 NA 值替换为同一行中狗的平均值。在第二步中,对猫进行同样的操作。 我尝试过类似的方法,但没有成功:

df[ , grepl("^.+(_dog)$", colnames(df))][is.na(df[ , grepl("^.+(_dog)$", colnames(df))])]
<- df$dog_mean[is.na(df[ , grepl("^.+(_dog)$", colnames(df))])]

不胜感激!

与其尝试一步完成转换,不如调用 lapply 一次转换一列(我在这里使用 magrittr只是为了节省两次输入整个第一行:

library( magrittr )
df[ , grepl("^.+(_dog)$", colnames(df))] %<>%
    lapply( function( x, vals ) {
        ifelse( is.na( x ), vals, x )
    },
    vals = df$dog_mean )

猫也一样:

df[ , grepl("^.+(_cat)$", colnames(df))] %<>%
    lapply( function( x, vals ) {
        ifelse( is.na( x ), vals, x )
    },
    vals = df$cat_mean )

在 base R 中,您可以通过两次 lapply:

# dogs
df[, grepl("_dog", names(df))] <- lapply(df[, grepl("_dog", names(df))],
                                       function(i) {i[is.na(i)] <- df$dog_mean[is.na(i)]; i})
# cats
df[, grepl("_cat", names(df))] <- lapply(df[, grepl("_cat", names(df))],
                                       function(i) {i[is.na(i)] <- df$cat_mean[is.na(i)]; i})

在这里,lapply returns 的列表被反馈到 data.frame 中的适当位置。 {} 确保整个代码块(两行,由 ; 分隔)一次性执行。