【问题标题】:Find and replace missing values with row mean用行均值查找和替换缺失值
【发布时间】:2013-07-22 16:01:17
【问题描述】:

我有一个带有 NA 的数据框,我想用行平均值替换 NA

c1 = c(1,2,3,NA)
c2 = c(3,1,NA,3)
c3 = c(2,1,3,1)

df = data.frame(c1,c2,c3)

> df
  c1 c2 c3
1  1  3  2
2  2  1  1
3  3 NA  3
4 NA  3  1

这样

> df
  c1 c2 c3
1  1  3  2
2  2  1  1
3  3  3  3
4  2  3  1

【问题讨论】:

    标签: r dataframe apply mean


    【解决方案1】:

    我的解决办法是

    rwmns = rowMeans(df,na.rm=TRUE)
    df$c1[is.na(df$c1)] = rwmns[is.na(df$c1)]
    df$c2[is.na(df$c2)] = rwmns[is.na(df$c2)]
    df$c3[is.na(df$c3)] = rwmns[is.na(df$c3)]
    > df
      c1 c2 c3
    1  1  3  2
    2  2  1  1
    3  3  3  3
    4  2  3  1
    

    有没有更优雅的方法,尤其是当某人有很多列时?

    【讨论】:

    • 出色的工作提出了您自己的解决方案。您可以使用[[ 来代替索引,因此每一行都变为df[[col_name]][is.na(df[[col_name]])] <- rwmns[is.na(df[[col_name]])。这样,您可以在要对其执行替换的列名称上循环或使用应用族。
    【解决方案2】:

    我认为这可行,

    df[which(is.na(df), arr.ind=TRUE)] <- rowMeans(df[!complete.cases(df), ], na.rm=TRUE)
    

    【讨论】:

    • 同时使用 is.na 和 complete.cases 有点多余;两行中可能有更有效的方法
    • 也许像这样? idx &lt;- which(is.na(df), arr.ind=TRUE); df[ idx ] &lt;- rowMeans( df[ idx[,1] , ], na.rm=TRUE)
    • @SimonO101 Jiber 打败了我们
    • 哈哈,是的,我刚刚看到了!
    • 为了多样化,我离开了这个;此外,complete.cases 部分可能在不同的情况下有用
    【解决方案3】:

    使用apply(注意返回的对象是matrix):

    t( apply( df , 1 , function(x) { x[ is.na(x) ] = mean( x , na.rm = TRUE ); x } ) )
         c1 c2 c3
    [1,]  1  3  2
    [2,]  2  1  1
    [3,]  3  3  3
    [4,]  2  3  1
    

    我们使用任何匿名函数将每一行中每个NA 的值更改为该行的mean。唯一的好处是,如果行数增加,您不必再进行任何输入。它在计算意义上不是特别有效或快速,但在认知意义上更是如此(除非你有 000,000 行,否则你不会注意到)。

    【讨论】:

      【解决方案4】:

      与@baptiste 的回答非常相似

      > ind <- which(is.na(df), arr.ind=TRUE)
      > df[ind] <- rowMeans(df,  na.rm = TRUE)[ind[,1]]
      

      【讨论】:

      • 我发现如果我有整行 NA,就会发生错误。将这个问题作为一个全新的问题提出是否合适?
      【解决方案5】:

      另一个选项是在转置数据集后从library(zoo)na.aggregate

      library(zoo)
      df[] <- t(na.aggregate(t(df)))
      df
      #  c1 c2 c3
      #1  1  3  2
      #2  2  1  1
      #3  3  3  3
      #4  2  3  1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-05
        • 2019-08-15
        • 2012-05-03
        • 2018-12-27
        • 1970-01-01
        • 2017-02-24
        • 2013-09-07
        相关资源
        最近更新 更多