如何使用dplyr独立过滤每列的行

pdu*_*ois 2 r dplyr tidyverse

我有以下几点:


library(tidyverse)
df <- tibble::tribble(
  ~gene, ~colB, ~colC,
  "a",   1,  2,
  "b",   2,  3,
  "c",   3,  4,
  "d",   1,  1
)

df
#> # A tibble: 4 x 3
#>    gene  colB  colC
#>   <chr> <dbl> <dbl>
#> 1     a     1     2
#> 2     b     2     3
#> 3     c     3     4
#> 4     d     1     1
Run Code Online (Sandbox Code Playgroud)

我想要做的是过滤列之后的每个列gene的值大于或等于2(> = 2).结果如下:

gene, colB, colC
a   NA   2
b   2    3
c   3    4
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

基因之后的列数实际上不仅仅是2.

nei*_*fws 5

一种解决方案:从宽格式转换为长格式,因此您可以仅过滤一列,然后根据需要在最后转换回宽格式。请注意,这将丢弃没有满足条件的值的基因。

library(tidyverse)
df %>% 
gather(name, value, -gene) %>% 
  filter(value >= 2) %>% 
  spread(name, value)

# A tibble: 3 x 3
   gene  colB  colC
* <chr> <dbl> <dbl>
1     a    NA     2
2     b     2     3
3     c     3     4
Run Code Online (Sandbox Code Playgroud)


ali*_*ire 5

即将推出的dplyr 0.6(现在从GitHub安装,如果你愿意的话)有filter_at,可用于过滤任何值大于或等于2的行,然后na_if可以类似地应用mutate_at,所以

df %>% 
    filter_at(vars(-gene), any_vars(. >= 2)) %>% 
    mutate_at(vars(-gene), funs(na_if(., . < 2)))
#> # A tibble: 3 x 3
#>    gene  colB  colC
#>   <chr> <dbl> <dbl>
#> 1     a    NA     2
#> 2     b     2     3
#> 3     c     3     4
Run Code Online (Sandbox Code Playgroud)

或类似地,

df %>% 
    mutate_at(vars(-gene), funs(na_if(., . < 2))) %>% 
    filter_at(vars(-gene), any_vars(!is.na(.)))
Run Code Online (Sandbox Code Playgroud)

可翻译用于dplyr 0.5:

df %>% 
    mutate_at(vars(-gene), funs(na_if(., . < 2))) %>% 
    filter(rowSums(is.na(.)) < (ncol(.) - 1))
Run Code Online (Sandbox Code Playgroud)

所有回报都是一样的.