【问题标题】:r - multiple variables in prop.test loop, output datar - prop.test 循环中的多个变量,输出数据
【发布时间】:2016-10-21 20:37:54
【问题描述】:

我无法在循环内创建prop.test 结果的数据框。我正在循环两个向量,它们指定运行多个prop.tests 所需的变量。我可以打印结果,但我想将结果放入数据框中。

样本数据:

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、statistic、parameter、p.value、estimate、conf.int、null.value、alternative、method、data.name。

【问题讨论】:

  • 查看broom::tidy

标签: r


【解决方案1】:

为了增加@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 包不可用,我们可以为htest 对象(如prop.test() 生成的对象)制作我们自己的tidy 方法的精简版本:

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)
}

将上述代码sn-p中的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)

【讨论】:

  • 不幸的是,我在工作机器上,无法安装扫帚包。有没有更基本的包装阵容的选项?
  • 感谢伟煌。这似乎很接近。这会产生错误
  • 感谢伟煌。这似乎很接近。这会在(函数(...,deparse.level = 1)中产生错误错误:无法将类型“闭包”强制转换为“列表”类型的向量
  • 我很抱歉。我的用户错误。这似乎工作得很好。谢谢伟煌。
猜你喜欢
  • 1970-01-01
  • 2016-08-18
  • 2018-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
  • 1970-01-01
相关资源
最近更新 更多