2017-02-09 41 views
1

我的问题:在单独的列替换与其他值不同的列分组的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))])] 

帮助非常感谢!

回答

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中的相应位置。 {}确保整个代码块(两行,由;分隔)一次执行。

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) 
相关问题