如何在data.table中计算大于index列的sim类列的行均值?
解决方法
这里有几种高效的方式实现你需要的计算,先看最直观且易读的方案:
方案1:使用apply按行处理
library(data.table) data <- setDT(data.frame(sim1=c(1,1,1), sim2= c(2,2,2), sim3=c(3,3,3), sim4=c(4,4,4), sim5=c(5,5,5), index=c(2,2,2))) # 计算每行sim列中大于index的均值 data[, higher.than.index.ave := apply(.SD, 1, function(x) { # 筛选当前行中大于index的sim值 filtered_vals <- x[x > index] # 处理无符合条件值的情况(可选,避免返回NaN) if (length(filtered_vals) == 0) NA_real_ else mean(filtered_vals) }), .SDcols = patterns("^sim")]
运行后你的data.table会得到预期结果:
sim1 sim2 sim3 sim4 sim5 index higher.than.index.ave 1: 1 2 3 4 5 2 4 2: 1 2 3 4 5 2 4 3: 1 2 3 4 5 2 4
方案2:使用rowMeans结合NA替换(更高效)
如果你的数据量较大,apply的行处理可能稍慢,可以用向量化操作替代:
data[, higher.than.index.ave := rowMeans( # 将不大于index的sim值替换为NA,再计算行均值(忽略NA) replace(.SD, .SD <= index, NA), na.rm = TRUE ), .SDcols = patterns("^sim")]
为什么你的原代码失效?
你之前的代码问题出在.SD[.SD > index]的逻辑:.SD是包含所有sim列的data.table,.SD > index会生成一个逻辑矩阵,但直接用.SD[.SD > index]会把所有行中满足条件的元素提取成一个长向量,而不是按行筛选对应的值。这就导致rowMeans计算的是整个向量的均值,而非每行的均值,自然得不到正确结果。
额外说明
.SDcols = patterns("^sim")是更简洁的方式选中所有以sim开头的列,替代了你原来复杂的grepl写法;- 如果需要处理无符合条件值的情况(比如某行index远大于所有sim值),可以根据需求调整:比如返回0、NA或者其他默认值。
内容的提问来源于stack exchange,提问作者Soheil
相关产品推荐
相关产品推荐

