R语言虚拟变量处理:行内1的数量>1时将后续变量设为NA
解决R语言中虚拟变量多1值的处理问题
嘿,作为R新手完全不用纠结术语的问题,咱们直接来解决你的需求——把每行第一个1之后的虚拟变量值改成NA。
首先先确认你的原始数据:
df <- structure(list(Dum_1 = c(1L, NA, NA), Dum_2 = c(NA, 1L, NA), Dum_3 = c(NA, 1L, 1L)), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"))
对应的表格展示:
# A tibble: 3 x 3 Dum_1 Dum_2 Dum_3 <int> <int> <int> 1 1 NA NA 2 NA 1 1 3 NA NA 1
你想要的结果是把第二行的Dum_3从1改成NA,下面给你两种可行的方法:
方法一:使用tidyverse(dplyr)处理
如果你习惯用tidyverse的语法,可以用rowwise()逐行操作,结合across()遍历所有列:
library(dplyr) df_processed <- df %>% rowwise() %>% mutate(across(everything(), ~ { # 找到当前行第一个1的位置 first_one_idx <- which(.x == 1)[1] if (!is.na(first_one_idx)) { # 获取当前列在数据框中的位置 current_col_idx <- which(cur_column() == names(df)) # 如果当前列在第一个1的位置之后,就设为NA,否则保留原值 if (current_col_idx > first_one_idx) NA else .x } else { # 没有1的行,直接保留原值 .x } })) %>% ungroup() # 查看结果 df_processed
运行后就能得到你想要的输出:
# A tibble: 3 x 3 Dum_1 Dum_2 Dum_3 <int> <int> <int> 1 1 NA NA 2 NA 1 NA 3 NA NA 1
方法二:使用Base R处理(无需额外包)
如果你不想加载dplyr,可以用Base R的apply()函数逐行处理:
# 逐行处理数据 processed_rows <- apply(df, 1, function(row) { # 找到该行第一个1的索引 first_one_pos <- which(row == 1)[1] if (!is.na(first_one_pos)) { # 将第一个1之后的所有值设为NA row[(first_one_pos + 1):length(row)] <- NA } row }) # 转置结果并转为tibble格式 df_processed <- as_tibble(t(processed_rows))
这个方法同样能得到和上面一致的结果,而且不需要安装额外的包。
两种方法的核心逻辑都是:找到每行第一个1的位置,然后把这个位置之后的所有虚拟变量值替换成NA,完美匹配你的需求~
内容的提问来源于stack exchange,提问作者Gil Van den Brande
相关产品推荐
相关产品推荐

