2017-05-29 102 views
2

我有以下tibble篩選每列行:如何使用獨立dplyr


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

[過濾基於特定值data.frame中的每一列(HTTPS的可能重複:// stackoverflow.com/questions/28183653/filter-each-column-of-a-data-frame-based-on-a-specific-value) – www

+1

我想你想''= 2'因爲2的值出現在所需的輸出。 – neilfws

+0

@neilfws:你是對的。我更新了。 – pdubois

回答

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 
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 

或者類似地,

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

可以翻譯爲與dplyr 0.5一起使用:

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

所有返回相同的東西。

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