我有一张大桌子,格式如下:
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我想制作一个类似于已发表的数字的数字。(F1.html):

基本上,对于每一行(基于公共Chrom和站点),我想看看中间值有多少。我在这里将中间值定义为15到85之间的值。然后,对于每个器官,我想知道在所有器官中有多少行是中间的,只有该器官,与两个或三个器官共用。
发布于 2015-05-21 19:06:23
展示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中间计数的器官法
对于中间层的数量,这会变得更加复杂。首先,使用reshape处理数据。
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我们只对真值感兴趣,因此[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现在剩下的就是通过每个器官获取唯一IAccs的计数,我们可以通过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")

发布于 2015-05-16 19:41:51
对于问题的第一部分(每一行都要找出中间值有多少),您可以尝试如下:
is_intermediate = function(x) {
return(x < 85 & x > 15)
}
res = sapply(Data[, 2:length(Data)], is_intermediate)
rowSums(res)如果您对dplyr + tidyr感到满意,您可以这样做:
Data %>% gather(organ, value, Heart:lungs) %>%
group_by(Chrom, Site) %>%
summarise(n_intermediate = sum(is_intermediate(value)))这将为每个Chrom / Site组合提供中间值。
在接下来的部分中,您可以这样做:
Data %>% select(-Chrom, -Site) %>%
mutate_each(funs(is_intermediate)) %>%
summarise_each(funs(sum))这将按列获得中间值的数目。
https://stackoverflow.com/questions/30261875
复制相似问题