r - prop.test循环中的多个变量,输出数据

时间:2016-10-21 20:37:54

标签: r

我在循环内创建prop.test结果的数据框时遇到问题。我循环两个向量,指定运行多个prop.test所需的变量。我能够打印结果,但我想把结果放到数据框中。

示例数据:

set.seed(1234)
tc <- sample(c("test", "control"), 1000, replace = TRUE, prob = c(.8, .2))
target <- sample(LETTERS[1:2], 1000, replace = TRUE, prob=c(1/3, 1/3, 1/3))
pa <- sample(c(0, 1), 1000, replace = TRUE)
sc <- sample(c(0, 1), 1000, replace = TRUE)
ig <- sample(c(0, 1), 1000, replace = TRUE)
test <- data.frame(tc, target, pa, sc, ig)

使用变量运行prop.test循环:

#define loop variables
target_var <- c("A", "B")   #targets
metric <- c("pa", "sc", "ig")   #columns to loop through

#loop through combinations of targets and metrics and run prop.test

for (i in target_var) {
  for (j in metric) {
    d <- subset(test, target == i)
    X <- d[,"tc"]
    Y <- d[,j]

    print(prop.test(table(X,Y),c(1,0),alternative="two.sided",
                    conf.level=0.95, correct=FALSE))       
  }
}

我不确定如何将所有prop.test运行的测试结果写入数据框。具体来说,我需要每次测试运行的i,j,统计,参数,p.value,估计,conf.int,null.value,alternative,method,data.name。

1 个答案:

答案 0 :(得分:0)

要增加@ alistaire的评论:您可以调用broom::tidyprop.test输出转换为数据帧,然后将调用包装在几个do.call(rbind, lapply(...))构造中:

library(broom)
out <- do.call(rbind, lapply(c("A", "B"), function(i) {
    do.call(rbind, lapply(c("pa", "sc", "ig"), function(j) {
        d <- subset(test, target == i)
        X <- d[,"tc"]
        Y <- d[,j]
        tidy(prop.test(table(X,Y),c(1,0),alternative="two.sided",
                    conf.level=0.95, correct=FALSE))
    }))
}))

内部lapply创建一个长度为3的列表(对于“pa”,“sc”和“ig”),列表中的每个元素都是tidy(prop.table(...))返回的数据帧,我们然后rbind在一起;外lapply创建一个长度为2的列表(对于“A”,“B”),每个元素都是内循环返回的数据帧,我们再次rbind一起。

我们可以通过向数据框添加target_varmetric来标识行来结束:

out <- cbind(
    setNames(expand.grid(c("pa", "sc", "ig"), c("A", "B")), c("metric", "target_var")),
    out)

输出:

out
#   metric target_var estimate1 estimate2  statistic    p.value parameter ...
# 1     pa          A 0.5142857 0.5169492 0.00153355 0.96876237         1 ...
# 2     sc          A 0.5142857 0.4872881 0.15742455 0.69153883         1 ...
# 3     ig          A 0.4285714 0.4915254 0.85764039 0.35439986         1 ...
# 4     pa          B 0.5000000 0.4629630 0.31977168 0.57174489         1 ...
# 5     sc          B 0.4324324 0.5592593 3.75231435 0.05273445         1 ...
# 6     ig          B 0.5540541 0.4851852 1.10190190 0.29384909         1 ...

如果broom包不可用,我们可以为tidy对象(例如htest生成的对象)制作我们自己的prop.test()方法的精简版本:

tidy.proptest <- function(x) {
    ret <- x[c("estimate", "statistic", "p.value", "parameter")]
    names(ret$estimate) <- paste0("estimate", seq_along(ret$estimate))
    ret <- c(ret$estimate, ret)
    ret$estimate <- NULL    
    ret <- c(ret, conf.low = x$conf.int[1], conf.high = x$conf.int[2],
        method = as.character(x$method),
        alternative = as.character(x$alternative))
    data.frame(ret)
}

在上面的代码段中将tidy替换为tidy.proptest。然后又做了几个步骤来美化输出:

rownames(out) <- seq_len(nrow(out)) # remove row names
out <- cbind(
    setNames(expand.grid(c("pa", "sc", "ig"), c("A", "B")), c("metric", "target_var")),
    out)