首页 > 解决方案 > 为每个样本列过滤出具有特定值的行

问题描述

在至少三个样本中保留 Obs 值超过样本阈值的行 (Obs)。删除具有 2 或更少的行。

IE。

.

df <- data.frame(column=c("threshold", "Obs1", "Obs2", "Obs3"), S1 = c(1.7,1.4,1.9,1.3), S2= c(0.9,0.8,2,1), S3=c(2.5,2.4,2.1,0.5), S4=c(0.4,0.5,0.6,0.9), S5=c(1.2,1.4,1.3,1.6))
 df

    column      S1  S2  S3  S4  S5
    threshold  1.7 0.9 2.5 0.4 1.2 
    Obs1       1.4 0.8 2.4 0.5 1.4 
    Obs2       1.9 2.0 2.1 0.6 1.3
    Obs3       1.3 1.0 0.5 0.9 1.6

期望的输出:

column      S1  S2  S3  S4  S5
 
Obs2       1.9 2.0 2.1 0.6 1.3
Obs3       1.3 1.0 0.5 0.9 1.6

我不知道如何编码,但我想知道是否使用这样的逻辑:

logic <- if df (S1-5)>= threshold value then =1; if df (S1-5) < threhold then = 0 

library(dplyr)
logic  %>% rowwise %%
    filter(sum(c_across(where(is.numeric))) >= 3) %>%
    ungroup

标签: rdplyr

解决方案


如果我们使用rowwisewith c_across,只使用slice没有“阈值”行的行,然后与具有“阈值”行>的相应sliced 数据集进行比较

library(dplyr)
df %>% 
    slice(-1) %>% 
    rowwise %>%
    filter(sum(c_across(where(is.numeric)) 
                > 
                  (df %>% 
                      slice(1) %>%
                   select(-1))) >=3) %>%
    ungroup

-输出

# A tibble: 2 x 6
#  column    S1    S2    S3    S4    S5
#  <chr>  <dbl> <dbl> <dbl> <dbl> <dbl>
#1 Obs2     1.9     2   2.1   0.6   1.3
#2 Obs3     1.3     1   0.5   0.9   1.6

如果还有其他字符列,我们可以更改select子集数据

df  %>% 
   slice(-1) %>%
   rowwise %>% 
   filter(sum(c_across(where(is.numeric)) > df %>%
             slice(1) %>%
             select(where(is.numeric))) >=3)

或另一种选择map

library(purrr)
library(magrittr)
i1 <- map(df %>%
              select(where(is.numeric)),  ~ .x[-1] >  first(.x)) %>% 
        reduce(`+`) %>% 
        is_greater_than(2)
df %>% 
     slice(-1) %>% 
     filter(i1)

base RrowSums

df[-1,][rowSums(df[-1, -1] > df[1, -1][col(df[-1, -1])]) >=3,]
#  column  S1 S2  S3  S4  S5
#3   Obs2 1.9  2 2.1 0.6 1.3
#4   Obs3 1.3  1 0.5 0.9 1.6

推荐阅读