如何解决通过其他列因子汇总列
我有一些数据,其中包含单个物种及其在每个样本中的计数。每个物种还以其营养模式标记。看起来像这样:
OTU_ID Trophic.Mode Sample1 Sample2 Sample3 Sample4
gatca Symbiotroph 4 5 6 1
atca Pathotroph 4 3 4 4
gatac Pathotroph 7 1 2 1
以此类推,它有2700行,带有标记其营养模式的物种计数。 我想聚合数据,以便按Trophic.Mode列(具有5个因素,所以我希望有5行的数据框)对每个样本建立一个更简单的功能社区,从而最终得到这个:
Trophic.Mode Sample1 Sample2 Sample3 Sample4
Symbiotroph 4 5 6 1
Pathotroph 13 18 15 11
因此,我使用了以下代码:
agg = aggregate(data,by = list(data$Trophic.Mode),FUN = sum)
这只会返回错误
"Error in Summary.factor(c(1L,2L,3L,4L,5L,6L,7L,8L,9L,10L,11L,:
‘sum’ not meaningful for factors
但是我不确定我是否理解-我想根据这些因素对其他列求和。
解决方法
我更喜欢将公式语法用于聚合,因为该公式右侧的分组列将自动从摘要中省略:
aggregate(. ~ Trophic.Mode,data = data[-1],FUN = sum)
如果您要对数据中不是列的内容进行分组,则带有by
的非公式接口最有用。
我想通过这些因素求和其他列。
这是rowsum
的作用:
rowsum(data[,-(1:2)],data$Trophic.Mode)
#R> Sample1 Sample2 Sample3 Sample4
#R> Pathotroph 11 4 6 5
#R> Symbiotroph 4 5 6 1
就击键和计算时间而言,这都是很难克服的:
# simulate your ~2700 row data set
set.seed(1)
n <- 2700L
sim_dat <- data.frame(
Trophic.Mode = sample.int(5,n,replace = TRUE),sample = matrix(sample.int(10,n * 4L,n))
colnames(sim_dat)[-1] <- paste0("sample",1:4)
head(sim_dat,3)
#R> Trophic.Mode sample1 sample2 sample3 sample4
#R> 1 1 9 6 9 6
#R> 2 4 1 6 3 1
#R> 3 1 9 9 10 9
# check that we get the same
r1 <- aggregate(. ~ Trophic.Mode,data = sim_dat,FUN = sum)
r2 <- rowsum(sim_dat[,-1],sim_dat$Trophic.Mode)
all.equal(r1[,r2,check.attributes = FALSE)
#R> [1] TRUE
library(tidyverse)
r3 <- sim_dat %>%
group_by(Trophic.Mode) %>%
summarise_all(sum) %>%
ungroup()
all.equal(r3[,check.attributes = FALSE)
#R> [1] TRUE
# check the computation time
bench::mark(
aggregate = aggregate(. ~ Trophic.Mode,FUN = sum),rowsum = rowsum(sim_dat[,sim_dat$Trophic.Mode),tidy = sim_dat %>%
group_by(Trophic.Mode) %>%
summarise_all(sum) %>%
ungroup(),min_time = 2,check = FALSE)
#R> # A tibble: 3 x 13
#R> expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time
#R> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm>
#R> 1 aggregate 2.28ms 2.45ms 396. 1.37MB 17.4 612 27 1.55s
#R> 2 rowsum 110.93µs 129.8µs 7449. 53.23KB 11.2 9985 15 1.34s
#R> 3 tidy 3.49ms 4.63ms 209. 93.41KB 6.56 383 12 1.83s
这几乎比其他方法快20倍,但是从几毫秒开始就没有...
更新
根据要求,这是具有n <- 500000L
(500k行)且没有ungroup
的基准:
bench::mark(
aggregate = aggregate(. ~ Trophic.Mode,tidy = sim_dat %>%
group_by(Trophic.Mode) %>%
summarise_all(sum),check = FALSE)
#R> # A tibble: 3 x 13
#R> expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time
#R> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm>
#R> 1 aggregate 203.5ms 264.5ms 3.64 234.56MB 25.5 8 56 2.19s
#R> 2 rowsum 11ms 11.2ms 84.8 7.82MB 14.0 170 28 2s
#R> 3 tidy 12.8ms 13.4ms 64.8 17.36MB 25.9 130 52 2s
,对于n <- 10000000L
(10M):
bench::mark(
aggregate = aggregate(. ~ Trophic.Mode,min_time = 30,check = FALSE)
#R> expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time
#R> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm>
#R> 1 aggregate 5.82s 5.92s 0.168 5.05GB 2.18 6 78 35.8s
#R> 2 rowsum 275.46ms 285.37ms 3.41 204.29MB 0.796 103 24 30.2s
#R> 3 tidy 233.38ms 264.47ms 3.66 331.03MB 2.03 110 61 30.1s
事实证明,较大的数据集几乎没有什么区别。
,library(tidyverse)
df %>%
select(-OTU_ID) %>%
group_by(Trophic.Mode) %>%
summarise_all(sum) %>%
ungroup()
我的偏好是tidyverse
。
也许尝试此选项。这是一个base R
选项。正如 @GregorThomas 在评论中所说,您必须告诉函数必须考虑哪些变量。在这种情况下,我们在公式中避免使用OTU_ID
。这里的代码:
#Option 1
Out1 <- aggregate(cbind(Sample1,Sample2,Sample3,Sample4)~Trophic.Mode,data=df,sum,na.rm=T)
输出:
Trophic.Mode Sample1 Sample2 Sample3 Sample4
1 Pathotroph 11 4 6 5
2 Symbiotroph 4 5 6 1
使用了一些数据:
#Data
df <- structure(list(OTU_ID = c("gatca","atca","gatac"),Trophic.Mode = c("Symbiotroph","Pathotroph","Pathotroph"),Sample1 = c(4L,4L,7L),Sample2 = c(5L,3L,1L),Sample3 = c(6L,2L),Sample4 = c(1L,1L)),class = "data.frame",row.names = c(NA,-3L))
,
尝试这个
library(dplyr)
read_table("TU_ID Trophic.Mode Sample1 Sample2 Sample3 Sample4
gatca Symbiotroph 4 5 6 1
atca Pathotroph 4 3 4 4
gatac Pathotroph 7 1 2 1") %>%
group_by(Trophic.Mode) %>%
summarise(across(where(is.numeric),sum))
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 2 x 5
Trophic.Mode Sample1 Sample2 Sample3 Sample4
<chr> <dbl> <dbl> <dbl> <dbl>
1 Pathotroph 11 4 6 5
2 Symbiotroph 4 5 6 1
,
请考虑一下aggregate
的公式版本,因为您可以显式地看到数字和分组列,因此可以更容易阅读。但是您可能仍需要过滤公式列。
也请注意aggregate
公式与非公式方法在处理缺失值方面可能有所不同。参见aggregate methods treat missing values (NA) differently。 @Rorschach的fix在下面应用。
# EXPLICIT NUMERIC COLUMNS
agg <- aggregate(cbind(Sample1,Sample4) ~ Trophic.Mode,data = data,FUN = sum,na.rm = TRUE,na.action = na.pass)
# IMPLICIT "ALL" NUMERIC COLUMNS
agg <- aggregate(. ~ Trophic.Mode,data = data[,grep("Trophic|Sample",names(data))],na.action = na.pass)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。