首页 > 解决方案 > 如何按行获取非零元素的平均值,改变条件使用哪些列

问题描述

假设我有以下数据表:

  tempmat=matrix(c(1,1,0,4,1,0,0,4,0,1,0,4, 0,0,1,4, 0,0,0,5),5,4,byrow=T)
  tempmat=rbind(rep(0,4),tempmat)
  tempmat=data.table(tempmat)
  names(tempmat)=paste0('prod1vint',1:4)

看起来像:

       prod1vint1 prod1vint2 prod1vint3 prod1vint4
1:          0          0          0          0
2:          1          1          0          4
3:          1          0          0          4
4:          0          1          0          4
5:          0          0          1          4
6:          0          0          0          5

我想定义一个新列 TN,它以下列方式逐行取平均值。

  1. 对于每一行,找到从左到右的第一个非零元素。
  2. 然后,找到右侧所有非零元素的平均值。

输出应该是:

   prod1vint1 prod1vint2 prod1vint3 prod1vint4   TN
1:          0          0          0          0   NA
2:          1          1          0          4   2.5
3:          1          0          0          4   4
4:          0          1          0          4   4
5:          0          0          1          4   4 
6:          0          0          0          5   NA

NA 的出现是因为在 1 中:没有非零元素,在 6 中:在第一个非零元素的右侧没有非零元素。

标签: rdplyrdata.tablebooleanaggregate

解决方案


使用apply逐行,我们可以首先找出行中不为 0 的索引。然后计算mean非零值if,至少有一个非零值,并且非零值不存在于最后一列elsereturnNA中。

tempmat$TN <- apply(tempmat, 1, function(x) {
           inds <- x != 0
           if (any(inds) & which.max(inds) != length(x)) 
             mean(Filter(function(f) f > 0, x[(which.max(inds) + 1) : length(x)]))
           else  
              NA
            })

tempmat
#   prod1vint1 prod1vint2 prod1vint3 prod1vint4  TN
#1:          0          0          0          0  NA
#2:          1          1          0          4 2.5
#3:          1          0          0          4 4.0
#4:          0          1          0          4 4.0
#5:          0          0          1          4 4.0
#6:          0          0          0          5  NA

推荐阅读