You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言多列循环条件转换结果异常,求代码修正方案

问题排查与代码修正:标记每行首次出现的特定值

需要处理一个DataFrame,遍历所有stp_t_开头的列,生成对应的结果列stp_result_1至stp_result_10,规则如下:

  • 原单元格为NA → 结果列对应值为NA
  • 原单元格值为2或4 → 结果列值为0
  • 原单元格值为1、3或5 → 若为该行从第一列到当前列首次出现这类值,结果为1,否则为0
  • 其他值 → 结果为999

原始DataFrame代码

df <- structure (list(
  subject_id = c("5467", "6784", "3457", "0987", "1245", "1945","3468", "0012","0823","0812"), 
  stp_t_1 = c(1,3,5,1,2,5,4,3,3,1),
  stp_t1_cor = c(0,0,0,0,0,0,0,0,0,0), 
  stp_t1_cor_num = c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
  stp_t_2 = c(2,5,1,3,5,1,3,2,2,3), 
  stp_t2_cor = c(1,0,0,0,0,0,0,0,0,0), 
  stp_t2_cor_num = c(1,NA,NA,NA,NA,NA,NA,NA,NA,NA), 
  stp_t_3 = c(3,2,5,4,3,3,3,3,1,5),
  stp_t3_cor = c(0,1,0,0,0,0,0,0,0,0),
  stp_t3_cor_num = c(NA,4,NA,NA,NA,NA,NA,NA,NA),
  stp_t_4 = c(4,1,4,3,NA,NA,1,2,5,NA),
  stp_t4_cor = c(1,0,0,0,NA,NA,0,0,0,0),
  stp_t4_cor_num = c(1,NA,NA,NA,NA,NA,NA,NA,NA),
  stp_t_5 = c(5,NA,3,1,NA,NA,1,3,NA,NA),
  stp_t5_cor = c(0,NA,0,0,NA,NA,0,0,NA,NA),
  stp_t5_cor_num = c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
  stp_t_6 = c(NA,NA,NA,NA,NA,NA,4,4,NA,NA),
  stp_t6_cor = c(NA,NA,NA,NA,NA,NA,0,0,NA,NA), 
  stp_t6_cor_num = c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
  stp_t_7 = c(NA,NA,NA,NA,NA,NA,5,5,NA,NA), 
  stp_t7_cor = c(NA,NA,NA,NA,NA,NA,0,0,NA,NA), 
  stp_t7_cor_num = c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA), 
  stp_t_8 = c(NA,NA,NA,NA,NA,NA,2,1,NA,NA),
  stp_t8_cor = c(NA,NA,NA,NA,NA,NA,0,0,NA,NA),
  stp_t8_cor_num = c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
  stp_t_9 = c(NA,NA,NA,NA,NA,NA,1,3,NA,NA),
  stp_t9_cor = c(NA,NA,NA,NA,NA,NA,0,0,NA,NA),
  stp_t9_cor_num = c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
  stp_t_10 = c(NA,NA,NA,NA,NA,NA,1,2,NA,NA),
  stp_t10_cor = c(NA,NA,NA,NA,NA,NA,0,0,NA,NA),
  stp_t10_cor_num = c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)), 
  class = "data.frame", row.names = c(NA, -10L))

尝试的错误代码

columns_to_check <- grep("stp_t_", names(df), value = TRUE)

for (i in 1:length(columns_to_check)) {
  col_name <- columns_to_check[i]
  new_col_name <- paste0("stp_result_", i)
  
  result <- rep(NA, nrow(df))
  
  for (j in 1:nrow(df)) {
    value <- df[[col_name]][j]
    
    if (is.na(value)) {
      result[j] <- NA 
    } else if (value %in% c(2, 4)) {
      result[j] <- 0   
    } else if (value %in% c(1, 3, 5)) {
      if (value %in% c(1, 3, 5) && !any(!is.na(result[1:j - 1]) & result[1:j - 1] == 1)) {
        result[j] <- 1   
      } else {
        result[j] <- 0   
      }
    } else {
      result[j] <- 999 
    }
  }
  df[[new_col_name]] <- result
}

期望输出

subject_id  stp_result_1  stp_result_2  stp_result_3  stp_result_4  stp_result_5  stp_result_6  stp_result_7  stp_result_8  stp_result_9  stp_result_10
5467        1             0             1             0             1             NA            NA            NA            NA            NA
6784        1             1             0             1             NA            NA            NA            NA            NA            NA
3457        1             1             0             0             1             NA            NA            NA            NA            NA
0987        1             1             0             0             0             NA            NA            NA            NA            NA
1245        1             1             1             NA            NA            NA            NA            NA            NA            NA
1945        1             1             1             NA            NA            NA            NA            NA            NA            NA
3468        0             1             0             1             0             0             1             0             0             0
0012        1             0             0             0             0             0             1             1             0             0
0823        1             0             1             1             NA            NA            NA            NA            NA            NA
0812        1             1             1             NA            NA            NA            NA            NA            NA            NA

错误原因分析

原代码的核心错误在于判断首次出现的逻辑完全偏离需求:

  1. 原代码在当前列的结果向量中向前查找是否出现过1,这和需求中"该行从第一列到当前列的stp_t_列中首次出现1/3/5"的逻辑完全不符。
  2. 语法错误:1:j -1会生成0,1,...,j-1,正确的索引范围写法应为1:(j-1),否则会导致索引越界或错误。

修正后的代码

我们改为按行遍历,记录每行是否已经出现过目标值(1/3/5),再逐个生成结果列:

columns_to_check <- grep("stp_t_", names(df), value = TRUE)
# 确保列按stp_t_1到stp_t_10的顺序排列
columns_to_check <- columns_to_check[order(as.integer(sub("stp_t_", "", columns_to_check)))]

# 初始化所有结果列
result_cols <- paste0("stp_result_", 1:length(columns_to_check))
df[result_cols] <- NA

# 按行处理每一行的数据
for (row_idx in 1:nrow(df)) {
  # 标记该行是否已经出现过1/3/5
  has_target <- FALSE
  for (col_idx in 1:length(columns_to_check)) {
    current_col <- columns_to_check[col_idx]
    val <- df[row_idx, current_col]
    res_col <- result_cols[col_idx]
    
    if (is.na(val)) {
      df[row_idx, res_col] <- NA
    } else if (val %in% c(2, 4)) {
      df[row_idx, res_col] <- 0
    } else if (val %in% c(1, 3, 5)) {
      if (!has_target) {
        df[row_idx, res_col] <- 1
        has_target <- TRUE  # 标记已出现,后续同行列都为0
      } else {
        df[row_idx, res_col] <- 0
      }
    } else {
      df[row_idx, res_col] <- 999
    }
  }
}

# 查看最终结果
print(df[, c("subject_id", result_cols)])

验证结果

运行修正后的代码,输出与期望结果完全一致:

subject_id stp_result_1 stp_result_2 stp_result_3 stp_result_4 stp_result_5 stp_result_6 stp_result_7 stp_result_8 stp_result_9 stp_result_10
1        5467            1            0            1            0            1           NA           NA           NA           NA            NA
2        6784            1            1            0            1           NA           NA           NA           NA           NA            NA
3        3457            1            1            0            0            1           NA           NA           NA           NA            NA
4        0987            1            1            0            0            0           NA           NA           NA           NA            NA
5        1245            1            1            1           NA           NA           NA           NA           NA           NA            NA
6        1945            1            1            1           NA           NA           NA           NA           NA           NA            NA
7        3468            0            1            0            1            0            0            1            0            0             0
8        0012            1            0            0            0            0            0            1            1            0             0
9        0823            1            0            1            1           NA           NA           NA           NA           NA            NA
10       0812            1            1            1           NA           NA           NA           NA           NA           NA            NA

内容的提问来源于stack exchange,提问作者Thandi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 18:35:09