我有以下几点:
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
我想要做的是过滤gene
列后的每一列
对于大于或等于2(> = 2)的值。结果如下:
gene, colB, colC
a NA 2
b 2 3
c 3 4
我怎样才能做到这一点?
基因之后的列数实际上不仅仅是2。
答案 0 :(得分:5)
即将推出的dplyr 0.6(现在从GitHub安装,如果你愿意的话)有filter_at
,它可用于过滤任何值大于或等于2的行,然后{{1} }可以通过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
可以翻译用于dplyr 0.5:
df %>%
mutate_at(vars(-gene), funs(na_if(., . < 2))) %>%
filter_at(vars(-gene), any_vars(!is.na(.)))
所有回报都是一样的。
答案 1 :(得分:4)
一种解决方案:从宽格式转换为长格式,因此您可以只对一列进行过滤,然后根据需要在最后转换回宽度。请注意,这将丢弃没有值满足条件的基因。
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
答案 2 :(得分:0)
我们可以使用data.table
library(data.table)
setDT(df)[df[, Reduce(`|`, lapply(.SD, `>=`, 2)), .SDcols = colB:colC]
][, (2:3) := lapply(.SD, function(x) replace(x, x < 2, NA)), .SDcols = colB:colC][]
# gene colB colC
#1: a NA 2
#2: b 2 3
#3: c 3 4
或melt/dcast
dcast(melt(setDT(df), id.var = 'gene')[value>=2], gene ~variable)
# gene colB colC
#1: a NA 2
#2: b 2 3
#3: c 3 4