如何在R中按分组列筛选行:保留至少一组全非零的代谢物行
筛选满足组内全非零条件的代谢物行
我需要移除那些**在任意列组的所有列中都不满足阈值(此处为大于0)**的行。我的数据包含两个样本组A和B,每组各有3个重复列,共3个代谢物观测值:
metabolites A1 A2 A3 B1 B2 B3 1 m1 3.703345 1.417572 3.388284 1.480509 2.612082 0.5997665 2 m2 0.000000 4.114684 2.659948 1.517864 2.690435 0.3141896 3 m3 0.000000 1.196729 1.373320 0.000000 3.943517 1.8687265
需求明确:保留代谢物m1和m2的行(至少在一个组的所有重复列中均为非零值),移除m3(A组和B组的重复列中都存在零值)。
我尝试了以下方法但未成功,仅将零值转换为NA,并未移除目标行:
# 构建数据框 metabolites <- paste0("m", 1:3) A1 <- c(rnorm(1, 2, 1), 0, 0) A2 <- c(rnorm(3, 2, 1)) A3 <- c(rnorm(3, 2, 1)) B1 <- c(rnorm(2, 2, 1), 0) B2 <- c(rnorm(3, 2, 1)) B3 <- c(rnorm(3, 2, 1)) df <- data.frame(metabolites, A1, A2, A3, B1, B2, B3) # 筛选操作——转回宽格式后并未移除目标代谢物行 df_filt <- df_long %>% group_by(group) %>% filter(value > 0) %>% ungroup() %>% mutate(group = NULL) %>% pivot_wider(names_from = samples,values_from = value) df_filt # 输出结果 # A tibble: 3 x 7 # Groups: metabolites [3] metabolites A1 A2 A3 B1 B2 B3 <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 m1 2.26 2.49 2.34 3.37 1.37 2.60 2 m2 NA 1.97 3.83 1.06 0.567 2.19 3 m3 NA NA 1.82 NA 3.07 0.255
可行解决方案
直接在宽格式下针对每组列做全非零判断,筛选出至少满足一个组条件的行即可,以下两种方法都能实现需求:
方法1:使用dplyr的rowwise + c_across
适合列数较多的场景,通过定义组列名批量判断:
library(dplyr) # 定义两组的列名集合 group_A <- c("A1", "A2", "A3") group_B <- c("B1", "B2", "B3") df_filtered <- df %>% rowwise() %>% filter( # 满足A组所有值>0 或者 B组所有值>0 all(c_across(all_of(group_A)) > 0) | all(c_across(all_of(group_B)) > 0) ) %>% ungroup()
方法2:直接生成判断列筛选
适合列数较少的场景,写法更直观:
df_filtered <- df %>% mutate( # 判断是否满足A组全非零 pass_A = all(A1 > 0, A2 > 0, A3 > 0), # 判断是否满足B组全非零 pass_B = all(B1 > 0, B2 > 0, B3 > 0) ) %>% # 保留至少满足一组的行 filter(pass_A | pass_B) %>% # 移除临时判断列 select(-pass_A, -pass_B)
最终输出结果
两种方法都会得到目标数据框:
metabolites A1 A2 A3 B1 B2 B3 1 m1 3.703345 1.417572 3.388284 1.480509 2.612082 0.5997665 2 m2 0.000000 4.114684 2.659948 1.517864 2.690435 0.3141896
内容的提问来源于stack exchange,提问作者Mikki
相关产品推荐
相关产品推荐

