我有以下几点:
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.
一种解决方案:从宽格式转换为长格式,因此您可以仅过滤一列,然后根据需要在最后转换回宽格式。请注意,这将丢弃没有满足条件的值的基因。
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)
即将推出的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)
所有回报都是一样的.