R:在不创建新变量的情况下测试因子的每个级别
R: Testing each level of a factor without creating new variables
假设我有一个包含二进制分组变量和一个因子的数据框。这种分组变量的一个示例可以指定对实验的处理和控制条件的分配。下面,b是分组变量,而a是任意因子变量:
a <- c("a","a","a","b","b")
b <- c(0,0,1,0,1)
df <- data.frame(a,b)
我想完成双样本 t 检验以评估以下内容:
- 对于 a 的每个级别,在 b 中指定的组之间采用该级别的平均倾向是否存在差异.
我已经使用 dummies 包为因子的每个水平创建单独的虚拟变量,然后对结果变量手动执行 t 检验:
library(dummies)
new <- dummy.data.frame(df, names = "a")
t.test(new$aa, new$b)
t.test(new$ab, new$b)
我正在寻求以下方面的帮助:
- 有没有一种方法可以在不通过 dummy.data.frame() 创建大量虚拟变量的情况下执行此操作?
- 如果在不创建大量虚拟变量的情况下没有更快的方法,那么有没有更快的方法来完成跨多列的 t 检验?
备注
这与 and nearly the same as this question Apply t-test on many columns in a dataframe split by factor类似但不同,但该问题的解决方案不再有效。
从统计的角度来看,我不完全理解这是在做什么,但是这段代码生成了一个列表,其中每个元素都是上面 t.test()
你 运行 的输出:
a <- c("a","a","a","b","b")
b <- c(0,0,1,0,1)
df <- data.frame(a,b)
library(dplyr)
library(tidyr)
dfNew<-df %>% group_by(a) %>% summarise(count = n()) %>% spread(a, count)
lapply(1:ncol(dfNew), function (x)
t.test(c(rep(1, dfNew[1,x]), rep(0, length(b)-dfNew[1,x])), b))
这将节省您连续输入 t.test(foo, bar)
的时间,并且还消除了对虚拟变量的需要。
编辑:我认为上述方法不会保留列的 顺序 ,仅保留测量为 0 或 1 的值的频率。如果顺序很重要(同样,我不知道这个过程的目标)那么你可以使用虚拟方法和 lapply
通过你命名为 new.
的 data.frame
library(dummies)
new <- dummy.data.frame(df, names = "a")
lapply(1:(ncol(new)-1), function(x)
t.test(new[,x], new[,ncol(new)]))
这是一个基础 R
解决方案,它实现了 卡方检验的比例相等性 ,我相信它更有可能回答您提出的任何问题你的数据(见我上面的评论):
set.seed(1)
## generate similar but larger/more complex toy dataset
a <- sample(letters[1:4], 100, replace = T)
b <- sample(0:1, 10, replace = T)
head((df <- data.frame(a,b)))
a b
1 b 1
2 b 0
3 c 0
4 d 1
5 a 1
6 d 0
## create a set of contingency tables for proportions
## of each level of df$a to the others
cTbls <- lapply(unique(a), function(x) table(df$a==x, df$b))
## apply chi-squared test to each contingency table
results <- lapply(cTbls, prop.test, correct = FALSE)
## preserve names
names(results) <- unique(a)
## only one result displayed for sake of space:
results$b
2-sample test for equality of proportions without continuity
correction
data: X[[i]]
X-squared = 0.18382, df = 1, p-value = 0.6681
alternative hypothesis: two.sided
95 percent confidence interval:
-0.2557295 0.1638177
sample estimates:
prop 1 prop 2
0.4852941 0.5312500
但是请注意,您可能不想在不更正 multiple comparisons 的情况下解释您的 p 值。快速模拟表明,使用至少一项检验错误拒绝原假设的几率可能大大高于 5%(!) :
set.seed(11)
sum(
replicate(1e4, {
a <- sample(letters[1:4], 100, replace = T)
b <- sample(0:1, 100, replace = T)
df <- data.frame(a,b)
cTbls <- lapply(unique(a), function(x) table(df$a==x, df$b))
results <- lapply(cTbls, prop.test, correct = FALSE)
any(lapply(results, function(x) x$p.value < .05))
})
) / 1e4
[1] 0.1642
假设我有一个包含二进制分组变量和一个因子的数据框。这种分组变量的一个示例可以指定对实验的处理和控制条件的分配。下面,b是分组变量,而a是任意因子变量:
a <- c("a","a","a","b","b")
b <- c(0,0,1,0,1)
df <- data.frame(a,b)
我想完成双样本 t 检验以评估以下内容:
- 对于 a 的每个级别,在 b 中指定的组之间采用该级别的平均倾向是否存在差异.
我已经使用 dummies 包为因子的每个水平创建单独的虚拟变量,然后对结果变量手动执行 t 检验:
library(dummies)
new <- dummy.data.frame(df, names = "a")
t.test(new$aa, new$b)
t.test(new$ab, new$b)
我正在寻求以下方面的帮助:
- 有没有一种方法可以在不通过 dummy.data.frame() 创建大量虚拟变量的情况下执行此操作?
- 如果在不创建大量虚拟变量的情况下没有更快的方法,那么有没有更快的方法来完成跨多列的 t 检验?
备注
这与
从统计的角度来看,我不完全理解这是在做什么,但是这段代码生成了一个列表,其中每个元素都是上面 t.test()
你 运行 的输出:
a <- c("a","a","a","b","b")
b <- c(0,0,1,0,1)
df <- data.frame(a,b)
library(dplyr)
library(tidyr)
dfNew<-df %>% group_by(a) %>% summarise(count = n()) %>% spread(a, count)
lapply(1:ncol(dfNew), function (x)
t.test(c(rep(1, dfNew[1,x]), rep(0, length(b)-dfNew[1,x])), b))
这将节省您连续输入 t.test(foo, bar)
的时间,并且还消除了对虚拟变量的需要。
编辑:我认为上述方法不会保留列的 顺序 ,仅保留测量为 0 或 1 的值的频率。如果顺序很重要(同样,我不知道这个过程的目标)那么你可以使用虚拟方法和 lapply
通过你命名为 new.
data.frame
library(dummies)
new <- dummy.data.frame(df, names = "a")
lapply(1:(ncol(new)-1), function(x)
t.test(new[,x], new[,ncol(new)]))
这是一个基础 R
解决方案,它实现了 卡方检验的比例相等性 ,我相信它更有可能回答您提出的任何问题你的数据(见我上面的评论):
set.seed(1)
## generate similar but larger/more complex toy dataset
a <- sample(letters[1:4], 100, replace = T)
b <- sample(0:1, 10, replace = T)
head((df <- data.frame(a,b)))
a b
1 b 1
2 b 0
3 c 0
4 d 1
5 a 1
6 d 0
## create a set of contingency tables for proportions
## of each level of df$a to the others
cTbls <- lapply(unique(a), function(x) table(df$a==x, df$b))
## apply chi-squared test to each contingency table
results <- lapply(cTbls, prop.test, correct = FALSE)
## preserve names
names(results) <- unique(a)
## only one result displayed for sake of space:
results$b
2-sample test for equality of proportions without continuity
correction
data: X[[i]]
X-squared = 0.18382, df = 1, p-value = 0.6681
alternative hypothesis: two.sided
95 percent confidence interval:
-0.2557295 0.1638177
sample estimates:
prop 1 prop 2
0.4852941 0.5312500
但是请注意,您可能不想在不更正 multiple comparisons 的情况下解释您的 p 值。快速模拟表明,使用至少一项检验错误拒绝原假设的几率可能大大高于 5%(!) :
set.seed(11)
sum(
replicate(1e4, {
a <- sample(letters[1:4], 100, replace = T)
b <- sample(0:1, 100, replace = T)
df <- data.frame(a,b)
cTbls <- lapply(unique(a), function(x) table(df$a==x, df$b))
results <- lapply(cTbls, prop.test, correct = FALSE)
any(lapply(results, function(x) x$p.value < .05))
})
) / 1e4
[1] 0.1642