我怀疑 MattParker 的评论将是这里最重要的事情:您正在将单个数字与向量进行比较,并且t.test
会抱怨这一点。由于您建议您要对每个分组变量 ( id
) 执行测试,因此在基础 R 中您可能希望使用类似by
(或split
) 的函数。dplyr
(内部也有很好的方法data.table
。)
使用mtcars
作为样本数据,我将尝试模仿您的数据:
dat <- mtcars[c("cyl", "mpg")]
colnames(dat) <- c("id", "ratio")
不清楚你的意思是用于dist
,所以我会使用天真的
dist <- 1:10
现在你可以这样做:
by(dat$ratio, dat$id, function(x) t.test(x, dist, paired = FALSE)$p.value)
# dat$id: 4
# [1] 2.660716e-10
# ------------------------------------------------------------
# dat$id: 6
# [1] 4.826322e-09
# ------------------------------------------------------------
# dat$id: 8
# [1] 2.367184e-07
如果您想/需要处理的不仅仅是ratio
一次,您也可以这样做:
by(dat, dat$id, function(x) t.test(x$ratio, dist, paired = FALSE)$p.value)
# dat$id: 4
# [1] 2.660716e-10
# ------------------------------------------------------------
# dat$id: 6
# [1] 4.826322e-09
# ------------------------------------------------------------
# dat$id: 8
# [1] 2.367184e-07
调用的结果by
是一个 class "by"
,它实际上只是一个list
带有一些额外属性的重新包装:
res <- by(dat, dat$id, function(x) t.test(x$ratio, dist, paired = FALSE)$p.value)
class(res)
# [1] "by"
str(attributes(res))
# List of 4
# $ dim : int 3
# $ dimnames:List of 1
# ..$ dat$id: chr [1:3] "4" "6" "8"
# $ call : language by.data.frame(data = dat, INDICES = dat$id, FUN = function(x) t.test(x$ratio, dist, paired = FALSE)$p.value)
# $ class : chr "by"
因此,您可以扩展/访问它,但是您可以list
:
res[[1]]
# [1] 2.660716e-10
as.numeric(res)
# [1] 2.660716e-10 4.826322e-09 2.367184e-07
names(res)
# [1] "4" "6" "8"
(意识到 的不同级别dat$id
是整数 4、6 和 8,所以names
应该对应于您的$id
。)
编辑:
如果您想要 data.frame 中的结果,可以想到两个选项:
- 对每一行重复 p 值,导致大量重复。我不鼓励这种方法有几个原因;如果您在某些时候需要它,我建议使用选项 2,然后
merge
.
生成一个具有与 unique 一样多的行的 data.frame id
。就像是:
do.call(rbind.data.frame,
by(dat, dat$id, function(x) list(id=x$id[1], pv=t.test(x, dist, paired=F)$p.value)))
# id pv
# 4 4 1.319941e-03
# 6 6 2.877065e-03
# 8 8 6.670216e-05