我有一个大表格,格式如下:
Data <- data.frame("Chrom" = c("chr1", "chr1", "chr1", "chr4", "chr4", "chr6"), "Site" = c(100, 200, 400, 140, 300, 400), "Heart" = c(20, 100, 0, 35, 92, 100), "Brain" = c(30, 40, 55, 100, 0, 100), "Liver" = c(100, 55, 20, 90, 0, 0), "Lungs" = c(100, 0, 80, 40, 30, 0))
,并提供:
> Data
Chrom Site Heart Brain Liver Lungs
1 chr1 100 20 30 100 100
2 chr1 200 100 40 55 0
3 chr1 400 0 55 20 80
4 chr4 140 35 100 90 40
5 chr4 300 92 0 0 30
6 chr6 400 100 100 0 0
我想制作一个类似于这个公布的数字的数字。 (http://www.nature.com/ncomms/2015/150218/ncomms7363/fig_tab/ncomms7363_F1.html):
基本上每行(基于常见的Chrom和Site),我想看看有多少个中间值。我在这里将中间值定义为15到85之间的值。然后,对于每个器官,我想知道在所有器官中间有多少行,只有器官,与两个器官共用或三个。
答案 0 :(得分:4)
展示data.table的强大功能:
<强>设置强>
library(data.table)
Data <- data.frame("Chrom" = c("chr1", "chr1", "chr1", "chr4", "chr4", "chr6"), "Site" = c(100, 200, 400, 140, 300, 400), "Heart" = c(20, 100, 0, 35, 92, 100), "Brain" = c(30, 40, 55, 100, 0, 100), "Liver" = c(100, 55, 20, 90, 0, 0), "Lungs" = c(100, 0, 80, 40, 30, 0))
DT <- data.table(Data)
isintermediate <- function(x){
return(x >=15 & x <= 85)
}
DI <- DT[ , list(Chrom, Site,
Heart = isintermediate(Heart),
Brain = isintermediate(Brain),
Liver = isintermediate(Liver),
Lungs = isintermediate(Lungs))]
这会创建一个矩阵DI
,如下所示:
> DI
Chrom Site Heart Brain Liver Lungs
1: chr1 100 TRUE TRUE FALSE FALSE
2: chr1 200 FALSE TRUE TRUE FALSE
3: chr1 400 FALSE TRUE TRUE TRUE
4: chr4 140 TRUE FALSE FALSE TRUE
5: chr4 300 FALSE FALSE FALSE TRUE
6: chr6 400 FALSE FALSE FALSE FALSE
如果值是中间值,则使用TRUE
或FALSE
。 (可能比创建函数更快速地完成此操作,但我觉得这很容易理解。)
计算中级
现在,通过Chrom + Site计算中间值很简单
# NoI is Number Intermediate
> DI[, list(NoI = Heart + Brain + Liver + Lungs), by = c("Chrom","Site")]
Chrom Site NoI
1: chr1 100 2
2: chr1 200 2
3: chr1 400 3
4: chr4 140 2
5: chr4 300 1
6: chr6 400 0
中级依据计数
对于中间跨越的数量,这变得更复杂。首先,使用重塑
来融化数据library(reshape2)
DA <- melt(DI, id.vars = c("Chrom","Site"))[value == TRUE]
这给出了:
> DA
Chrom Site variable value
1: chr1 100 Heart TRUE
2: chr4 140 Heart TRUE
3: chr1 100 Brain TRUE
4: chr1 200 Brain TRUE
5: chr1 400 Brain TRUE
6: chr1 200 Liver TRUE
7: chr1 400 Liver TRUE
8: chr1 400 Lungs TRUE
9: chr4 140 Lungs TRUE
10: chr4 300 Lungs TRUE
我们只对TRUE值感兴趣,因此[value == TRUE]
行
现在我们需要为每个站点计算中间值,但为每个器官附加。我们可以使用.N
和by=
来执行此操作,然后合并回我们的初始表:
DA <- merge(DA,DA[, list(IAcc = .N), by = c("Chrom","Site")], by = c("Chrom","Site"))
,并提供:
> DA
Chrom Site variable value IAcc
1: chr1 100 Heart TRUE 2
2: chr1 100 Brain TRUE 2
3: chr1 200 Brain TRUE 2
4: chr1 200 Liver TRUE 2
5: chr1 400 Brain TRUE 3
6: chr1 400 Liver TRUE 3
7: chr1 400 Lungs TRUE 3
8: chr4 140 Heart TRUE 2
9: chr4 140 Lungs TRUE 2
10: chr4 300 Lungs TRUE 1
现在剩下的就是获得每个器官的唯一IAcc数量,我们可以使用table
函数获得:
Output <- data.table(table(DA[,list(variable,IAcc)]))
> Output
variable IAcc N
1: Heart 1 0
2: Brain 1 0
3: Liver 1 0
4: Lungs 1 1
5: Heart 2 2
6: Brain 2 2
7: Liver 2 1
8: Lungs 2 1
9: Heart 3 0
10: Brain 3 1
11: Liver 3 1
12: Lungs 3 1
其中IAcc
是器官(包括其自身)的数量,它们在同一个Chrom和Site上也有一个中间值,N是看到的次数。
最后,绘制(原谅默认颜色):
library(ggplot2)
ggplot(Output, aes(x = variable, y = N, fill = IAcc)) + geom_bar(stat = "identity")
答案 1 :(得分:2)
对于问题的第一部分(对于每一行,找到有多少中间值),您可以尝试以下方法:
Data %>% gather(organ, value, Heart:lungs) %>%
group_by(Chrom, Site) %>%
summarise(n_intermediate = sum(is_intermediate(value)))
如果您对dplyr + tidyr感到满意,可以执行以下操作:
Data %>% select(-Chrom, -Site) %>%
mutate_each(funs(is_intermediate)) %>%
summarise_each(funs(sum))
这将为您提供每个Chrom / Site组合的中间值数量。
对于下一部分,您可以执行以下操作:
Azure DocumentDB
这将按列获取中间值的数量。