我试图用同一列中同一列中出现的另一个值来填充所有NA,是否有一种简单的方法可以做到这一点?我发现了几乎所有功能,但并不是这样。
data.frame看起来像这样
id month price1 price2
1 1 NA 2
2 1 4 NA
3 1 NA NA
1 2 6 NA
2 2 NA NA
3 2 NA 4
输出应如下所示:
id month price1 price2
1 1 4 2
2 1 4 2
3 1 4 2
1 2 6 4
2 2 6 4
3 2 6 4
答案 0 :(得分:1)
一种可能的方法是使用match
函数。
d <- data.frame(id = rep(1:3, 2),
month = rep(1:2, each=3),
price1 = c(NA, 4, NA, 6, NA, NA),
price2 = c(2, NA, NA, NA, NA, 4))
d[is.na(d$price1), "price1"] <-
d[!is.na(d$price1), ][match(d[is.na(d$price1), "month"],
d[!is.na(d$price1), "month"]), "price1"]
d[is.na(d$price2), "price2"] <-
d[!is.na(d$price2), ][match(d[is.na(d$price2), "month"],
d[!is.na(d$price2), "month"]), "price2"]
> d
id month price1 price2
1 1 1 4 2
2 2 1 4 2
3 3 1 4 2
4 1 2 6 4
5 2 2 6 4
6 3 2 6 4
请注意,如果有多个非缺失值可供选择,则此方法将使用第一个非缺失值。
正如Laterow所建议的那样,你可以遍历变量:
for (j in 3:ncol(d)) {
varname <- names(d)[j]
d[is.na(d[, varname]), varname] <-
d[!is.na(d[, varname]), ][match(d[is.na(d[, varname]), "month"],
d[!is.na(d[, varname]), "month"]),
varname]
}
答案 1 :(得分:0)
这个问题在StackExchange中可能会更好,因为它专注于R中的编程,但这是一个答案:
我想有更好的方法可以做到这一点,但会立即浮现在脑海中。
replace_nas <- function(df,var,id_var,func = function(x) x[!is.na(x)])
return( merge(df[,-which(names(df)==var)],aggregate(as.formula(paste0(var,"~",id_var)),df,func))[,var])
replace_all_nas <- function(df,id_vars,select_var,agg_vars,func = function(x) x[!is.na(x)])
return(cbind(df[,id_vars],sapply(agg_vars,function(x) replace_nas(df,x,select_var,func))))
用法:使用df调用replace_all_nas作为要执行此操作的data.frame,id_vars是要修复的列名称的向量,select_var是要组织的变量,agg_vars是变量如果要替换NAs,则func是您要用来收集非na值以替换NA的函数。我将其设置为选择非NA值,假设只有一个,但如果列中有多个非NA值,则需要其他方法来处理此问题。
运行你的例子:
replace_all_nas(blah,id_vars = c("id","month"),select_var = c("month"),agg_vars = c("price1","price2"),func = function(x) x[!is.na(x)])
# id month price1 price2
# 1 1 1 4 2
# 2 2 1 4 2
# 3 3 1 4 2
# 4 1 2 6 4
# 5 2 2 6 4
# 6 3 2 6 4
答案 2 :(得分:0)
dplyr
解决方案。它假设每个“月”在NA的旁边都有一个值。
为每个月创建一个包含单个列的数据框,并在其中创建包含单个值的新变量。
d1 <- d %>% group_by(month)
%>% summarise(price1a = mean(price1,na.rm=TRUE),price2a=mean(price2,na.rm=TRUE))
将新列附加到原始数据框。
dplyr::left_join(d,d1,by="month")
id month price1 price2 price1a price2a
1 1 1 NA 2 4 2
2 2 1 4 NA 4 2
3 3 1 NA NA 4 2
4 1 2 6 NA 6 4
5 2 2 NA NA 6 4
6 3 2 NA 4 6 4
答案 3 :(得分:0)
一种方法是使用ave
。函数可以应用于具有ave
的相同因子级别的组。
ave(df$price1, df$month, FUN=function(x)unique(x[!is.na(x)]))
#[1] 4 4 4 6 6 6
ave(df$price2, df$month, FUN=function(x)unique(x[!is.na(x)]))
#[1] 2 2 2 4 4 4