根据行中是否存在数据查找所有可能的组合

时间:2018-02-19 09:43:18

标签: r combinations multiple-columns

我正在使用大型数据框,其中列中有许多空行(NA),称为Ion Score。基本上,这个分数是某些蛋白质的鉴定。

我的数据框的一般结构是:

N | Accession |  Ion Score1    | Ion Score2 | Ion Score3 | 
1 | 4322      |  5             | 5          | 5          | 
2 | 2344      |  5             | NA         | 5          | 
3 | 2341      |  NA            | 5          | NA         |   
4 | 2346      |  NA            | NA         | 5          |   
5 | 2346      |  5             | NA         | NA         |  
6 | 2348      |  NA            |  5         | 5          |  
7 | 2349      |  5             | 5          | NA         | 

我想拥有的是这样的:

df1:
N | Accession |  Ion Score1    | Ion Score2 | Ion Score3 | 
1 | 4322      |  5             | 5          | 5          | 

df2:
N | Accession |  Ion Score1    | Ion Score2 | Ion Score3 |
2 | 2349      |  5             | 5          | NA         | 

df3: 
N | Accession |  Ion Score1    | Ion Score2 | Ion Score3 |
3 | 2344      |  5             | NA         | 5          |  

df4:
N | Accession |  Ion Score1    | Ion Score2 | Ion Score3 |
5 | 2347      |  NA            | NA         | 5          |  
.
. 
.

等等,考虑到所有可能的组合。

在获得具有所有可能组合的数据表的情况下,更具说明性的示例是:

N | Accession |  Ion Score1    | Ion Score2 | Ion Score3 | 
1 | 4322      |  5             | 5          | 5          | 
2 | 2349      |  5             | 5          | NA         | 
3 | 2344      |  5             | NA         | 5          |   
4 | 2348      |  NA            | 5          | 5          | 
5 | 2347      |  NA            | NA         | 5          | 
6 | 2341      |  NA            | 5          | NA         | 
7 | 2349      |  5             | NA         | NA         |  

为了使它更清晰,通过这种方式,我可以看到哪些是三个共同的,两个共同的和那些仅在样本中共有的。

我认为最好的方法是在R中使用组合。 然后尝试对列进行筛选,排序和分组。

首先,我使用它来了解可能的组合数量

#Where N is the number of combinations, in this case 3. 
Combination_table <- data.frame(expand.grid(rep(list(0:1), 19))) 
#invert row order
Combination_table <- Combination_table[-nrow(Combination_table), ] 

然后按照组合过滤并创建一个新数据框:

df1 <- data.frame(Proteins[!is.na(Proteins$Ion Score) &
                               !is.na(Proteins$Ion Score2) &
                               !is.na(Proteins$Ion Score3), ])
df2 <- data.frame(Proteins[!is.na(Proteins$Ion Score) &
                               is.na(Proteins$Ion Score2) &
                               !is.na(Proteins$Ion Score3), ])
df3 <- data.frame(Proteins[!is.na(Proteins$Ion Score) &
                               !is.na(Proteins$Ion Score2) &
                               is.na(Proteins$Ion Score3), ])
df4 <- data.frame(Proteins[is.na(Proteins$Ion Score) &
                               is.na(Proteins$Ion Score2) &
                               !is.na(Proteins$Ion Score3), ])
.
.
.

这很有效,问题在于我有很多Ion Score列。例如,9个Ion Score列= 512种可能的组合。

你知道另一种方法吗?

示例数据集:

Proteins <- data.frame(N = c(1, 2, 3, 4), Accession = c(4322, 
    222, 2344, 2341), `Ion Score1` = c(5, 5, "NA", "NA"), `Ion Score2` = c(5, 
    "NA", 5, 5), `Ion Score3` = c(5, 5, "NA", 5))

编辑:

N | Accession |  Ion Score1    | Ion Score2 | Ion Score3 | 
1 | 4322      |  3             | 51         | 12          | 
2 | 4533      |  7             | NA         | 87          | 
3 | 4125      |  NA            | 9          | NA          |  
4 | 8964      |  NA            | 9          | NA          |  
5 | 5454      |  NA            | 10         | NA         |  
6 | 9871      |  6             | 5          | NA          |  
7 | 7562      |  NA            | 5          | NA          |   
8 | 7894      |  8             | NA         | 5           |   
9 | 0189      |  5             | NA         | NA          |  
10| 8746      |  NA            |  45        | 54          |  
11| 8746      |  5             | 23          | NA         | 

示例:

Proteins <- data.frame(N = c(1, 2, 3, 4,5,6,7,8,9,10,11), Accession = c(4322,222, 2344, 2341,6598,98974,7889,78798,1212,4566,1148), `Ion Score1` = c(3, 7, "NA", "NA","NA",6,"NA",8,5,"NA",5), `Ion Score2` = c(51, "NA",9,9,10,5,5,"NA","NA",45, 23), `Ion Score3` = c(12,87,"NA","NA","NA","NA","NA", 5, "NA", 54,"NA"))

2 个答案:

答案 0 :(得分:1)

我认为您正在寻找expand.grid(),您可以使用它来制作所有组合的查找表(我在这里称之为x2)。然后,我遍历所有组合(即nrow(x2))并提取数据帧的匹配行。

Proteins <- data.frame(N = c(1, 2, 3, 4), Accession = c(4322, 
    222, 2344, 2341), `Ion Score1` = c(5, 5, NA, NA), `Ion Score2` = c(5, 
    NA, 5, 5), `Ion Score3` = c(5, 5, NA, 5), stringsAsFactors = F)

cols <- 3  # Number of 'Ion Score' columns

# make a grid of all combinations
x1 <- do.call(rep, args = list(list(c(1, NA)), cols))
x2 <- as.matrix(expand.grid(x1))

head(x2)
#>      Var1 Var2 Var3
#> [1,]    1    1    1
#> [2,]   NA    1    1
#> [3,]    1   NA    1
#> [4,]   NA   NA    1
#> [5,]    1    1   NA
#> [6,]   NA    1   NA

for (ii in seq_len(nrow(x2))) {
    idx <- apply(Proteins[, 3:5], 1, function(x) {
        isTRUE(all.equal(is.na(x), is.na(x2[ii, ]), check.attributes = FALSE, use.names = FALSE))
    })
    if (any(idx))
        assign(paste0("df", ii), Proteins[idx, ])
}

df1
#>   N Accession Ion.Score1 Ion.Score2 Ion.Score3
#> 1 1      4322          5          5          5
df2
#>   N Accession Ion.Score1 Ion.Score2 Ion.Score3
#> 4 4      2341         NA          5          5
df3
#>   N Accession Ion.Score1 Ion.Score2 Ion.Score3
#> 2 2       222          5         NA          5
df6
#>   N Accession Ion.Score1 Ion.Score2 Ion.Score3
#> 3 3      2344         NA          5         NA

请注意,我更改了Proteins数据集并创建了数字变量,而不是示例中的字符串因子。

答案 1 :(得分:1)

以下是使用split函数的解决方案。为了找到Ion分数的所有组合,我连接了NA's的索引,以创建一个唯一的可能性串。结果是一个列表,对我来说这是一种更好的方法来存储结果以供下游分析。

df <- split(Proteins, drop = T, 
           f = list(apply(Proteins[, -c(1:2)], 1, 
                                    function(x) paste(which(is.na(x)),
                                                      collapse = "") )))

# [[1]]
# N Accession Ion.Score1 Ion.Score2 Ion.Score3
# 1 1      4322          5          5          5
# 
# $`1`
# N Accession Ion.Score1 Ion.Score2 Ion.Score3
# 4 4      2341         NA          5          5
# 
# $`13`
# N Accession Ion.Score1 Ion.Score2 Ion.Score3
# 3 3      2344         NA          5         NA
# 
# $`2`
# N Accession Ion.Score1 Ion.Score2 Ion.Score3
# 2 2       222          5         NA          5