自动对 R 中数据框中的多个变量进行 t 检验和卡方检验
Automatically conducting t tests and chi square tests across multiple variables in a data frame in R
这是一些示例数据:
set.seed(1234) # Make the results reproducible
count <- 100
cs1 <- round(rchisq(count, 1), 2)
cs2 <- round(rchisq(count, 2), 2)
c(rep("Present", 30), rep("Absent", 30), rep("NA", 40)) -> temp
temp[temp == "NA"] <- NA
as.factor(temp) -> temp
temp1 <- round(rnorm(count, 3), 2)
temp1[7] <- NA
temp2 <- round(rnorm(count, 7), 2)
temp2[54] <- NA
c(rep("Yes", 30), rep("No", 30), rep("Maybe", 30), rep("NA", 10)) -> temp3
temp3[temp3 == "NA"] <- NA
as.factor(temp3) -> temp3
c(rep("Group A", 55), rep("Group B", 45)) -> temp4
as.factor(temp4) -> temp4
mydata <- data.frame(cs1, cs2, temp, temp1, temp2, temp3, temp4)
mydata$cs2[56:100] <- NA ; mydata
我知道我可以计算按 temp4
分层的每个变量的汇总统计信息,如下所示:
by(mydata, mydata$temp4, summary)
但是,我还想为按 temp4
分层的每个变量计算 t.test 或 chisq.test。我试过简单地修改上面的代码来做到这一点,但它总是给我一个错误。错误似乎源于数据框中的某些变量是数字(因此需要 t.test)而其他变量是因子(因此需要 chisq.test)这一事实。
有没有一种简单的方法告诉 R 检查变量以查看它是什么类型,然后 运行 立即进行适当的测试?并且即使遇到错误仍然打印出所有结果?
我不担心这样做是否合适(例如,我知道多次测试的风险等),而只是需要知道如何去做。谢谢!
是的,您可以遍历指定的列,将 temp4
作为因子,并检查每列的 class(在匿名函数中命名为 x
)。您可以使用 sapply
或 apply(X, MARGIN = 2, FUN ...)
。请注意,我明确地对 mydata
进行了子集化,因为我发现它更明确和可读。
sapply(mydata[, c("cs1", "cs2", "temp", "temp1", "temp2", "temp3")], FUN = function(x, group) {
if (class(x) == "numeric") {
# perform t-test, e.g. t.test(x ~ group)
return(result_of_t_test)
}
if (class(x) == "factor") {
# perform chi-square test
return(result_of_chisq_test)
}
}, group = mydata$temp4)
您可以使用 lapply
循环变量并在匿名函数内部决定进行哪个测试。
发生错误时,它会被 tryCatch
捕获,最终列表将包含错误消息作为成员,而不是测试结果。
tests_list <- lapply(mydata[-ncol(mydata)], function(x){
tryCatch({
if(is.numeric(x)){
if(length(levels(mydata$temp4)) == 2){
t.test(x ~ temp4, data = mydata)
}else{
aov(x ~ temp4, data = mydata)
}
}else{
tbl <- table(x, mydata$temp4)
chisq.test(tbl)
}
}, error = function(e) e)
})
err <- sapply(tests_list, inherits, "error")
tests_list$cs1
tests_list$temp3
tests_list[[err]]
这是一些示例数据:
set.seed(1234) # Make the results reproducible
count <- 100
cs1 <- round(rchisq(count, 1), 2)
cs2 <- round(rchisq(count, 2), 2)
c(rep("Present", 30), rep("Absent", 30), rep("NA", 40)) -> temp
temp[temp == "NA"] <- NA
as.factor(temp) -> temp
temp1 <- round(rnorm(count, 3), 2)
temp1[7] <- NA
temp2 <- round(rnorm(count, 7), 2)
temp2[54] <- NA
c(rep("Yes", 30), rep("No", 30), rep("Maybe", 30), rep("NA", 10)) -> temp3
temp3[temp3 == "NA"] <- NA
as.factor(temp3) -> temp3
c(rep("Group A", 55), rep("Group B", 45)) -> temp4
as.factor(temp4) -> temp4
mydata <- data.frame(cs1, cs2, temp, temp1, temp2, temp3, temp4)
mydata$cs2[56:100] <- NA ; mydata
我知道我可以计算按 temp4
分层的每个变量的汇总统计信息,如下所示:
by(mydata, mydata$temp4, summary)
但是,我还想为按 temp4
分层的每个变量计算 t.test 或 chisq.test。我试过简单地修改上面的代码来做到这一点,但它总是给我一个错误。错误似乎源于数据框中的某些变量是数字(因此需要 t.test)而其他变量是因子(因此需要 chisq.test)这一事实。
有没有一种简单的方法告诉 R 检查变量以查看它是什么类型,然后 运行 立即进行适当的测试?并且即使遇到错误仍然打印出所有结果?
我不担心这样做是否合适(例如,我知道多次测试的风险等),而只是需要知道如何去做。谢谢!
是的,您可以遍历指定的列,将 temp4
作为因子,并检查每列的 class(在匿名函数中命名为 x
)。您可以使用 sapply
或 apply(X, MARGIN = 2, FUN ...)
。请注意,我明确地对 mydata
进行了子集化,因为我发现它更明确和可读。
sapply(mydata[, c("cs1", "cs2", "temp", "temp1", "temp2", "temp3")], FUN = function(x, group) {
if (class(x) == "numeric") {
# perform t-test, e.g. t.test(x ~ group)
return(result_of_t_test)
}
if (class(x) == "factor") {
# perform chi-square test
return(result_of_chisq_test)
}
}, group = mydata$temp4)
您可以使用 lapply
循环变量并在匿名函数内部决定进行哪个测试。
发生错误时,它会被 tryCatch
捕获,最终列表将包含错误消息作为成员,而不是测试结果。
tests_list <- lapply(mydata[-ncol(mydata)], function(x){
tryCatch({
if(is.numeric(x)){
if(length(levels(mydata$temp4)) == 2){
t.test(x ~ temp4, data = mydata)
}else{
aov(x ~ temp4, data = mydata)
}
}else{
tbl <- table(x, mydata$temp4)
chisq.test(tbl)
}
}, error = function(e) e)
})
err <- sapply(tests_list, inherits, "error")
tests_list$cs1
tests_list$temp3
tests_list[[err]]