R语言:按条件对列样本跨行累加值?代码NA问题排查
问题描述
现有两个数据集gt_df和weights,结构如下:
dput(gt_df) structure(list(rs1 = c(1, 1), rs2 = c(0, 0), rs8 = c(1, 1), rs21 = c(0, 0)), row.names = c("1117F", "1XZ7S"), class = "data.frame") dput(weights) structure(list(varID = c("rs12", "rs8", "rs2"), weight = c(0.119982752530867, -0.0375093345760517, 0.0320329747257121)), row.names = c(NA, 3L), class = "data.frame")
需求逻辑:对gt_df中的每个样本(行),遍历所有列:
- 若列名存在于
weights$varID中,将该列值乘以对应weight - 否则乘以0
最终将该行所有计算结果累加得到预测值。
编写的循环代码运行后得到全NA的pred矩阵,无法得到正确结果。示例预期结果如下:
gt_Df: rs1 rs2 rs8 rs21 1117F 1 0 1 0 IIEI 1 0 1 1 weights file: varID weights rs21 0.119 rs8 -0.037 rs2 0.032 Expected outcome: Predicted_Value 1117F -0.037 11EI 0.082 Calculation: for 1117F: 1*0 + 0*0.032 +1*-0.037 + 0*0.119=-0.037
问题原因
原代码中pred初始化为含NA值的矩阵,第一次执行sum(pred1, pred[i])时,是数值加NA,结果仍为NA,后续累加也一直保持NA,这是核心问题。
解决方案
方法1:修改原循环代码
将pred初始化为全0矩阵,同时简化循环内的逻辑:
# 初始化全0矩阵,而非NA pred <- matrix(0, nrow=nrow(gt_df), ncol=1) colnames(pred) <- "Predicted" rownames(pred) <- rownames(gt_df) for(i in 1:nrow(gt_df)){ for(j in 1:ncol(gt_df)){ col_name <- colnames(gt_df)[j] if(col_name %in% weights$varID){ # 直接匹配varID对应的weight weight_val <- weights$weight[weights$varID == col_name] pred[i] <- pred[i] + gt_df[i,j] * weight_val } # 不匹配的情况乘以0,累加后不改变结果,可省略else分支 } }
运行后即可得到正确结果:
print(pred) # Predicted # 1117F -0.03750933 # 1XZ7S -0.03750933
方法2:向量化实现(更高效)
避免嵌套循环,利用R的向量化操作,代码更简洁且处理大数据集时性能更好:
# 为gt_df的每一列匹配对应的weight,无匹配则设为0 col_weights <- ifelse(colnames(gt_df) %in% weights$varID, weights$weight[match(colnames(gt_df), weights$varID)], 0) # 矩阵乘法计算每行加权和 pred <- data.frame(Predicted = as.matrix(gt_df) %*% col_weights) rownames(pred) <- rownames(gt_df)
执行结果与修改后的循环代码一致。
内容的提问来源于stack exchange,提问作者rheabedi1
相关产品推荐
相关产品推荐

