我有四列患者的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仍需完整无缺。
我在数据表方面做了一些工作,对数据框或数据表解决方案感到满意。
答案 0 :(得分:4)
我们在第2列:第5列中将“0”值转换为“NA”,然后将rowMeans
与na.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)))
这也可能有用。