如何在R语言中基于其他列的值条件性提取列数据?
问题描述
需要处理一个R数据框:仅当同编号的a_*和b_*列数值都大于4时,保留对应c_*列的原值;否则将c_*列对应位置设为NA,最终保留ID列和处理后的所有c_*列。
输入数据
data <- data.frame( ID = c("001", "002", "003"), a_1 = c(2, 5, 7), a_2 = c(7, 3, 2), a_3 = c(5, 5, 7), b_1 = c(1, 7, 3), b_2 = c(3, 3, 5), b_3 = c(5, 7, 7), c_1 = c("a", "b", "c"), c_2 = c("c", "a", "a"), c_3 = c("b", "a", "c") )
期望输出
data <- data.frame( ID = c("001", "002", "003"), c_1 = c(NA, "b", NA), c_2 = c(NA, NA, NA), c_3 = c("b", "a", "c") )
解决方案
方法1:Base R 向量化处理
利用列名的编号后缀规律,直接循环处理每组a/b/c列:
# 提取所有a列的编号后缀(1、2、3) suffixes <- sub("a_", "", grep("^a_", colnames(data), value = TRUE)) # 逐个处理每个编号组 for(suf in suffixes) { # 判断当前组的a和b是否都大于4 meet_condition <- data[[paste0("a_", suf)]] > 4 & data[[paste0("b_", suf)]] > 4 # 不满足条件的c列值替换为NA data[[paste0("c_", suf)]] <- ifelse(meet_condition, data[[paste0("c_", suf)]], NA) } # 只保留ID和处理后的c列 final_data <- data[, c("ID", grep("^c_", colnames(data), value = TRUE))] print(final_data)
方法2:Tidyverse 重塑处理
通过将数据转为长格式,更直观地筛选条件,再转回宽格式:
library(dplyr) library(tidyr) final_data <- data %>% # 转长格式,拆分列名为类型(a/b/c)和编号后缀 pivot_longer( cols = -ID, names_to = c(".value", "suffix"), names_pattern = "(.)_(.)" ) %>% # 仅保留满足条件的c值,其余设为NA mutate(c = ifelse(a > 4 & b > 4, c, NA)) %>% # 移除不需要的a、b列 select(-a, -b) %>% # 转回宽格式,恢复c_*列名 pivot_wider( names_from = suffix, names_prefix = "c_", values_from = c ) print(final_data)
内容的提问来源于stack exchange,提问作者Marie
相关产品推荐
相关产品推荐

