关于dplyr:如何计算数据框中的字符总数并使用R中的mutate添加列

How to count total character occurence in data frame and add column using mutate in R

我有一个数据帧(dat),其列的序列为(Seq)(字符类)。我正在尝试在每一行中拆分序列并计算'A''C''G''T'的数量,并使用mutate(在dplyr中)添加每一列。以下是我尝试的示例数据框架和代码。

1
2
3
   Seq
CAGGACATAA
TGTCCACTGC

我要执行的代码:

1
2
3
4
5
6
7
count_bases <- function (x){
    for(i in 1:length(x)){
        tab[i] <- table(strsplit((x)[i],""))
    }
    return(tab)
}
count_bases(dat$Seq)

如果我仅在第一行使用命令:table(strsplit(dat$Seq[1],"")),它可以正常工作并给出结果。我想要获得的所需输出是通过上述函数进行的,并变异为创建如下所示的数据帧:

1
2
3
    Seq    A C G T
CAGGACATAA 5 2 2 1
TGTCCACTGC 1 4 2 3


这是使用dplyr和tidyr的解决方案,该解决方案可以处理任何长度/组成的任意数量的序列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
library(tidyr)
library(dplyr)

dat <- data.frame(Seq = c("CAGGACATAA","TGTCCACTGC"),
                                      stringsAsFactors = F)

result <- dat %>%
            # explode each seq into indvidiual
            # characters on individual rows
            mutate(seq.split = strsplit(Seq,"")) %>%
            unnest() %>%  
            # count by each type of character in eah Seq
            group_by(Seq, seq.split) %>%
            summarise(n=n()) %>%
            # convert to wide table format
            spread(seq.split, n)

result
Source: local data frame [2 x 5]

         Seq     A     C     G     T
       (chr) (int) (int) (int) (int)
1 CAGGACATAA     5     2     2     1
2 TGTCCACTGC     1     4     2     3

有点大,但是您可以使用strsplit进行拆分,然后使用lapply遍历结果以构建表列表(或在lapply函数中进行拆分;无论您愿意使用什么)。然后,您可以使用do.call(rbind重新组合列表,然后使用data.frame将其添加到现有的data.frame中。您需要使用as.character将任何因子转换为字符串,并使用factor来确保table添加任何空级别。

1
2
3
4
5
6
7
8
9
dat <- data.frame(Seq = c("ACGACCGGG","CAGGACATAA","TGTCCACTGC"))

data.frame(dat, do.call(rbind, lapply(strsplit(as.character(dat$Seq), ''), function(x){
    table(factor(x, levels = c('A', 'C', 'G', 'T')))
})))
#          Seq A C G T
# 1  ACGACCGGG 2 3 4 0
# 2 CAGGACATAA 5 2 2 1
# 3 TGTCCACTGC 1 4 2 3