快速汇总跨列数据框的方法

时间:2019-08-27 21:04:01

标签: r dataframe dplyr bioinformatics summarize

我有五个可能的data.frame状态(character)中的genotypes

genotypes <- c("0/0","1/1","0/1","1/0","./.")
library(dplyr)
set.seed(1)
df <- do.call(rbind, lapply(1:100, function(i)
  matrix(sample(genotypes, 30, replace = T), nrow = 1, dimnames = list(NULL, paste0("V", 1:30))))) %>%
  data.frame()

我想将每一行总结成每行有多少:

  • ref.hom0/0
  • alt.hom1/1
  • het0/11/0
  • na./.

这似乎很慢:

sum.df <- do.call(rbind,lapply(1:nrow(df), function(i){
  data.frame(ref.hom = length(which(df[i,] == "0/0")),
             alt.hom = length(which(df[i,] == "1/1")),
             het = length(which(df[i,] == "0/1") | which(df[i,] == "1/0")),
             na = length(which(df[i,] == "./.")))
}))

有没有更有效的方法,也许是基于dplyr的方法?

3 个答案:

答案 0 :(得分:4)

对于基因分型数据,我将使用/** * findParentElementByClass, returns an parent element based on a * class name. This parent class name is chained off the required * child component. * * @param {String} parentClass // parent class * @param {String} componentClass // Element 4 class in your case * @return {Node} componentParent */ function findParentElementByClass(parentClass, componentClass) { let componentParent = document.querySelector(`.${componentClass}`).parentNode; for (let i = 0; i < 100; i++) { if (componentParent.classList.contains(`.${parentClass}`)) { break; } else { componentParent = componentParent.parentNode; } } return componentParent; } 。您将节省大量的RAM。

setDT()

执行时间检查:

library(data.table)
df$key <- 1:nrow(df)
df <- melt(setDT(df),id.vars = "key")
table(df$key, df$value) 

 # > head(table(df$key, df$value))
 #
 #   ./. 0/0 0/1 1/0 1/1
 # 1   6   6   4   7   7
 # 2   6   3   8   5   8
 # 3   7   3   5   5  10
 # 4   4   8   1   7  10
 # 5   5   9   4   3   9
 # 6   9   2   6   8   5
# and
table(df$value)
# > table(df$value)
# ./. 0/0 0/1 1/0 1/1 
# 620 581 601 584 614 

答案 1 :(得分:3)

使用dplyr,您可以尝试:

df %>%
 transmute(ref.hom = rowSums(. == "0/0"),
           alt.hom = rowSums(. == "1/1"),
           het = rowSums(. == "0/1") + rowSums(. == "1/0"),
           na = rowSums(. == "./."))

    ref.hom alt.hom het na
1         4      11   9  6
2         5       2  20  3
3         3      11  10  6
4         5       5  15  5
5         5       4  17  4
6         3       8  13  6
7         6       8  11  5
8         4       8  11  7
9         6       6  14  4
10       14       8   5  3

答案 2 :(得分:1)

在基数R中,您可以将applytable一起使用,这将返回每一行中所有可能级别的计数。

output <- t(apply(df, 1, table))
output

#     ./. 0/0 0/1 1/0 1/1
#[1,]   7   8   4   3   8
#[2,]   5   7   4   9   5
#[3,]   6   5   6   5   8
#[4,]   4   7   9   6   4
#[5,]   6   5   6   5   8
#[6,]   8   8   2   7   5
#....

以后,如果需要,可以将列合并为一个output[, 3] + output[, 4]级。


另一种选择是将数据gather转换为长格式,然后count

library(dplyr)

df %>%
  mutate(row = row_number()) %>%
  tidyr::gather(key, value, -row) %>%
  count(row, value)
  #If needed
  #tidyr::spread(value, n)