【问题标题】:Easiest way to replace non-NA values by column index用列索引替换非 NA 值的最简单方法
【发布时间】:2022-12-17 07:27:51
【问题描述】:

我有一个如下所示的数据框,其中包含一些 NA:

mydf=data.frame(ID=LETTERS[1:10], aaa=runif(10), bbb=runif(10), ccc=runif(10), ddd=runif(10))
mydf[c(1,4,5,7:10),2]=NA
mydf[c(1,2,4:8),3]=NA
mydf[c(3,4,6:10),4]=NA
mydf[c(1,3,4,6,9,10),5]=NA

> mydf
   ID       aaa       bbb        ccc       ddd
1   A        NA        NA 0.08844614        NA
2   B 0.4912790        NA 0.88925139 0.1233173
3   C 0.1325188 0.1389260         NA        NA
4   D        NA        NA         NA        NA
5   E        NA        NA 0.60750723 0.6357998
6   F 0.8218579        NA         NA        NA
7   G        NA        NA         NA 0.5988206
8   H        NA        NA         NA 0.4008338
9   I        NA 0.8784563         NA        NA
10  J        NA 0.2959320         NA        NA

我想在这里完成的是以下内容:

1- 将非 NA 值替换为 column index -1,以便输出如下所示:

> mydf
   ID       aaa       bbb        ccc       ddd
1   A        NA        NA          3        NA
2   B         1        NA          3         4
3   C         1         2         NA        NA
4   D        NA        NA         NA        NA
5   E        NA        NA          3         4
6   F         1        NA         NA        NA
7   G        NA        NA         NA         4
8   H        NA        NA         NA         4
9   I        NA         2         NA        NA
10  J        NA         2         NA        NA

2-然后我想添加一个额外的列来显示以下内容:

  • 0 表示一行中的所有 NA
  • 0 对于具有超过 1 个非 NA 值的行
  • 当它是一行中唯一的非NA值时的实际值

最终结果应如下所示:

> mydf
   ID       aaa       bbb        ccc       ddd       final
1   A        NA        NA          3        NA           3
2   B         1        NA          3         4           0
3   C         1         2         NA        NA           0
4   D        NA        NA         NA        NA           0
5   E        NA        NA          3         4           0
6   F         1        NA         NA        NA           1
7   G        NA        NA         NA         4           4
8   H        NA        NA         NA         4           4
9   I        NA         2         NA        NA           2
10  J        NA         2         NA        NA           2

我可能可以用一个丑陋的for循环来完成所有这些,然后将aggregate作为最后一列,并在适当的地方用0代替......

但我想知道是否有一种干净的方法可以在几行内通过一些 apply 调用来做到这一点......

谢谢!

【问题讨论】:

    标签: r dataframe na


    【解决方案1】:

    你可以这样做:

    mydf[-1] <- sapply(1:4, (x) x * mydf[x+1]/mydf[x+1])
    
    mydf$final <- apply(mydf[-1], 1, function(x) { 
      if(all(is.na(x)) | sum(!is.na(x)) > 1) 0 else na.omit(x)
    })
    

    结果:

    mydf
    #>    ID aaa bbb ccc ddd final
    #> 1   A  NA  NA   3  NA     3
    #> 2   B   1  NA   3   4     0
    #> 3   C   1   2  NA  NA     0
    #> 4   D  NA  NA  NA  NA     0
    #> 5   E  NA  NA   3   4     0
    #> 6   F   1  NA  NA  NA     1
    #> 7   G  NA  NA  NA   4     4
    #> 8   H  NA  NA  NA   4     4
    #> 9   I  NA   2  NA  NA     2
    #> 10  J  NA   2  NA  NA     2
    

    创建于 2022-12-16 reprex v2.0.2

    【讨论】:

      【解决方案2】:

      这是一个想法,

      mydf1 <- cbind.data.frame(ID = mydf$ID, mapply(function(x, y) replace(x, !is.na(x), y), mydf, seq(ncol(mydf)) - 1)[,-1])
      mydf1$final <- apply(mydf1[-1], 1, (i) ifelse(sum(is.na(i)) == (ncol(mydf) - 1)| sum(!is.na(i)) > 1, 0, i[!is.na(i)]))
      
      mydf1
         ID  aaa  bbb  ccc  ddd final
      1   A <NA> <NA>    3 <NA>     3
      2   B    1 <NA>    3    4     0
      3   C    1    2 <NA> <NA>     0
      4   D <NA> <NA> <NA> <NA>     0
      5   E <NA> <NA>    3    4     0
      6   F    1 <NA> <NA> <NA>     1
      7   G <NA> <NA> <NA>    4     4
      8   H <NA> <NA> <NA>    4     4
      9   I <NA>    2 <NA> <NA>     2
      10  J <NA>    2 <NA> <NA>     2
      

      【讨论】:

        猜你喜欢
        • 2011-12-05
        • 2020-06-17
        • 1970-01-01
        • 2019-06-27
        相关资源
        最近更新 更多