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

时间:2017-02-09 06:58:09

标签: r dataframe replace na

我的问题:

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))])]

非常感谢!

2 个答案:

答案 0 :(得分:1)

您可能最好只通过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 )

答案 1 :(得分:1)

在基础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返回的列表将反馈到data.frame中的相应位置。 {}确保整个代码块(两行,由;分隔,一次执行)。