根据其他列值复制列中的值

时间:2016-05-23 00:57:32

标签: r dataframe

我试图用同一列中同一列中出现的另一个值来填充所有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

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