R:查找多列的平均值,仅用于值> gt的列。 0

时间:2016-01-28 18:22:29

标签: r dataframe data.table

我有四列患者的BMI测量值。一些患者的测量值高于其他患者。 例如:

    id <- c(1, 2, 3, 4, 5)
    bmi1 <- c(18, 25, 20, 30, 32)
    bmi2 <- c(18, 0, 0, 31, 34)
    bmi3 <- c(20, 0, 0, 0, 31)
    bmi4 <- c(0, 0, 0, 0, 32)
    bmi <- data.frame(id, bmi1, bmi2, bmi3, bmi4)

我想创建第五列avg,它将四个bmi列[2:5]平均在一起,但不包括零。所以它看起来像这样:

      id bmi1 bmi2 bmi3 bmi4   avg
       1   18   18   20    0 18.67
       2   25    0    0    0 25.00
       3   20    0    0    0 20.00
       4   30   31    0    0 30.50
       5   32   34   31   32 32.50

因此,取第2行的平均值,它只会计算(25/1),但要取第1行的平均值,它将计算(18 + 18 + 20)/ 3。 ID仍需完整无缺。

我在数据表方面做了一些工作,对数据框或数据表解决方案感到满意。

4 个答案:

答案 0 :(得分:4)

我们在第2列:第5列中将“0”值转换为“NA”,然后将rowMeansna.rm=TRUE一起使用。

 bmi[2:5][bmi[2:5]==0]<- NA

或者@David Arenburg提到

 is.na(bmi[-1]) <- bmi[-1] == 0 #changes 0 values to NA
 bmi$avg <- round(rowMeans(bmi[2:5], na.rm=TRUE),2)
 bmi$avg
 #[1] 18.67 25.00 20.00 30.50 32.25

上述解决方案将原始数据集中的“0”值更改为“NA”,但如果我们不想更改原始“bmi”对象中的值,则使用replace和{{{ 1}}。

rowMeans

答案 1 :(得分:2)

以下是适用的基础解决方案:

bmi$avg=apply(bmi[,2:4],1,function(x) mean(x[x !=0 ]))

答案 2 :(得分:2)

这是另一种可能性

round(rowSums(bmi[-1]) / rowSums(bmi[-1] != 0), 2)
# [1] 18.67 25.00 20.00 30.50 32.25

这只是将行和除以每行非零值的数量。

或者(如果你没有NA s)我们想要避免矩阵转换

round(Reduce(`+`, bmi[-1]) / rowSums(bmi[-1] != 0), 2)

答案 3 :(得分:0)

 `%notin%` <- function(x,y) !(x %in% y)
  bmi$avg <- apply(bmi[2:4],1, function(x) sum(x) / length(which(bmi[x,1] %notin% 0)))

这也可能有用。

相关问题