确定非零单元的数量并通过分层变量计算流行率

时间:2015-03-17 18:27:10

标签: r

我花了很多时间环顾四周,无法找到解决我具体问题的方法。我真的很感激任何帮助。

我有一个大的data.frame(1258个障碍,共298个变量),其中每个行都是参与者样本记录,每个列都是样本中发现的特定细菌属。然后,我为每个参与者创建了多条记录,这也在列变量中显示。

以下是数据框的外观示例。

Corynebacterium <- c(0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.5, 0.7, 0.1, 0.0)
Paenibacillus <- c(0.0, 0.1, 0.7, 0.3, 0.5, 0.7, 0.0, 0.0, 0.0, 0.3, 0.3, 0.0)
Psychrobacter <- c(0.1, 0.1, 0.5, 0.0, 0.0, 0.0, 0.3, 0.6, 0.0, 0.6, 0.7, 0.0)
Staphylocccus <- c(0.5, 0.0, 0.3, 0.0, 0.3, 0.2, 0.5, 0.0, 0.4, 0.1, 0.1, 0.5)
TimePoint <- c("A", "B", "C", "D", "E", "F", "A", "B", "C", "D", "E", "F")
SampleDF <- data.frame(Corynebacterium, Paenibacillus, Psychrobacter, 
Staphylocccus, TimePoint)

我想知道给定时间点的非零单元总数超过单元总数。

例如:对于TimePoint A处的棒状杆菌,它将是#NonZeroCells / Total#Cells = 1/2 = 0.5。考虑到这一点的另一种方式是在时间点A处50%的棒状杆菌细胞是非零的。

4 个答案:

答案 0 :(得分:5)

这是一个 dplyr 答案:

SampleDF %>%
    group_by(TimePoint) %>%
    summarise_each(funs(sum(. != 0) / length(.)))

#   TimePoint Corynebacterium Paenibacillus Psychrobacter Staphylocccus
# 1         A             0.5           0.0           1.0           1.0
# 2         B             0.5           0.5           1.0           0.0
# 3         C             0.5           0.5           0.5           1.0
# 4         D             0.5           1.0           0.5           0.5
# 5         E             0.5           1.0           0.5           1.0
# 6         F             0.0           0.5           0.0           1.0

您也可以在基地R中非常简单地执行此操作:

aggregate(. ~ TimePoint, data=SampleDF, function(x) sum(x != 0) / length(x))

答案 1 :(得分:3)

就个人而言,如果我可以避免使用,我更喜欢在工作时不使用外部包装。如果你像我一样,做这样的事情的最好方法是使用aggregate()内置以及一些简单的自定义函数。

aggregate所做的是基于某些分组变量将数据框分成一堆较小的数据框,然后将每列传递给您选择的函数。您可以使用sum等内置函数,也可以编写自己的函数。

在您的情况下,您希望在每个分组中找到非零值的百分比。这是两个简单的例子。

func.simple_count <- function(data.vector) {

    return(sum(data.vector!=0))
}
aggregate(x = SampleDF[c("Corynebacterium","Paenibacillus","Psychrobacter","Staphylocccus")],
          by = list(SampleDF$TimePoint),
          FUN = func.simple_count)

输出:

  Group.1 Corynebacterium Paenibacillus Psychrobacter Staphylocccus
1       A               1             0             2             2
2       B               1             1             2             0
3       C               1             1             1             2
4       D               1             2             1             1
5       E               1             2             1             2
6       F               0             1             0             2

func.percent_nonzero <- function(data.vector) {

    return(sum(data.vector!=0)/length(data.vector))
}
aggregate(x = SampleDF[c("Corynebacterium","Paenibacillus","Psychrobacter","Staphylocccus")],
          by = list(SampleDF$TimePoint),
          FUN = func.percent_nonzero)

输出:

  Group.1 Corynebacterium Paenibacillus Psychrobacter Staphylocccus
1       A             0.5           0.0           1.0           1.0
2       B             0.5           0.5           1.0           0.0
3       C             0.5           0.5           0.5           1.0
4       D             0.5           1.0           0.5           0.5
5       E             0.5           1.0           0.5           1.0
6       F             0.0           0.5           0.0           1.0

在更大的数据框架上进行操作时,而不是像我一样在aggregate语句中明确列出变量,而是使用names()函数和!=来排除分组变量。

答案 2 :(得分:0)

这应该是一个好的开始。另请查看常规?table以及其他软件包,例如xtabs和来自CrossTable的{​​{1}}功能。更多信息here

gmodels

答案 3 :(得分:0)

使用data.table

library(data.table)
setDT(SampleDF)[, lapply(.SD, function(x) sum(x!=0)/.N) , by= TimePoint]
#   TimePoint Corynebacterium Paenibacillus Psychrobacter Staphylocccus
#1:         A             0.5           0.0           1.0           1.0
#2:         B             0.5           0.5           1.0           0.0
#3:         C             0.5           0.5           0.5           1.0
#4:         D             0.5           1.0           0.5           0.5
#5:         E             0.5           1.0           0.5           1.0
#6:         F             0.0           0.5           0.0           1.0