R语言按条件将数据框列值向后填充的实现方法
R语言按行条件填充列值实现方案
你可以通过for循环、apply函数或者向量化操作实现需求,以下是可直接运行的代码:
首先加载原始测试数据:
# 构造原始数据集 ID <- c("A", "B", "C", "D", "E", "F") Q0 <- c(0, 0, 0, 0, 0, 0) Q1 <- c(0, 1, 0, 0, NA, 1) Q2 <- c(0, NA, 1, 0, NA, 1) Q3 <- c(0, NA, NA, 1, NA, 1) Q4 <- c(0, NA, NA, 1, NA, 1) dta <- data.frame(ID, Q0, Q1, Q2, Q3, Q4) # 定位所有需要处理的Q列位置,排除非数值的ID列 q_cols <- grep("^Q", colnames(dta))
方法1:for循环实现(逻辑最易读)
逐行遍历,用标记位记录当前行是否已经遇到取值为1的列,遇到后将后续所有Q列赋值为1即可:
res1 <- dta for (i in seq_len(nrow(res1))) { has_found_1 <- FALSE for (j in q_cols) { if (has_found_1) { res1[i, j] <- 1 } else { current_val <- res1[i, j] if (!is.na(current_val) && current_val == 1) { has_found_1 <- TRUE } } } }
方法2:apply函数实现
按行传入处理函数,定位每行第一个1的位置,将该位置及之后的所有列值设为1:
res2 <- dta res2[, q_cols] <- t(apply(dta[, q_cols], 1, function(row) { first_1_idx <- which(!is.na(row) & row == 1)[1] if (!is.na(first_1_idx)) { row[first_1_idx:length(row)] <- 1 } return(row) }))
方法3:向量化实现(大数据量下效率最高)
借助累积最大值判断逻辑,避免显式循环,运行速度远快于前两种方法:
res3 <- dta q_matrix <- as.matrix(dta[, q_cols]) # 将NA临时替换为0做累积最大值计算,识别每行1首次出现后的所有位置 hit_mask <- t(apply(t(q_matrix), 2, function(col) { cummax(replace(col, is.na(col), 0)) })) # 命中位置统一赋值为1,未命中位置保留原始值(0或NA) q_matrix[hit_mask == 1] <- 1 res3[, q_cols] <- q_matrix
三种方法输出的结果完全匹配预期:
ID Q0 Q1 Q2 Q3 Q4 1 A 0 0 0 0 0 2 B 0 1 1 1 1 3 C 0 0 1 1 1 4 D 0 0 0 1 1 5 E 0 NA NA NA NA 6 F 0 1 1 1 1
内容的提问来源于stack exchange,提问作者nattys
相关产品推荐
相关产品推荐

