【问题标题】:Use loop for multiple testing in data frame在数据框中使用循环进行多次测试
【发布时间】:2017-03-08 13:07:36
【问题描述】:

我想要一个通用函数来对数据框中的数据执行多个 t.tests,并使用以下示例数据:

dat <- data.frame(ID=c(1:100),
                  DRUG= rep(c("D1","D2","D2","D3","D3","D3","D5","D1","D4","D2"),10),
                  ADR=rep(c("A1","A2","A3","A6","A7","A8","A4","A2","A1","A2"),10),
                  X= sample(1:250, 100, replace=F))

基本上,我想针对 DRUG - ADR 的每个独特组合的 X 值运行两个 t.test。如果我以 D1-A1 为例,我想测试 D1-A1 与 D1-A1 的 X 值以及 D1-A1 与 D1-A1 的 X 值。下面是我对这个例子的语法,但我的问题是如何制作一个通用循环/函数来对 DRUG - ADR 的每个独特组合执行两个测试。

x <- ifelse (dat$DRUG == "D1" & dat$ADR == "A1",dat$X, NA)
x <- x[!is.na(x)]

y <- ifelse (dat$DRUG != "D1" & dat$ADR == "A1",dat$X, NA)
y <- y[!is.na(y)]

z <- ifelse (dat$DRUG == "D1" & dat$ADR != "A1",dat$X, NA)
z <- z[!is.na(z)]

t.test(x,y)
t.test(x,z)

因此,对于第 4 条记录 (D3-A6),语法为:

x <- ifelse (dat$DRUG == "D3" & dat$ADR == "A6",dat$X, NA)
x <- x[!is.na(x)]

y <- ifelse (dat$DRUG != "D3" & dat$ADR == "A6",dat$X, NA)
y <- y[!is.na(y)]

z <- ifelse (dat$DRUG == "D3" & dat$ADR != "A6",dat$X, NA)
z <- z[!is.na(z)]

t.test(x,y)
t.test(x,z)

谁知道通用函数的好主意?

编辑:我的理想结果如下表:

  Drug ADR pvalue1 pvalue2
1   D1  A1  pval11  pval21
2   D2  A2  pval12  pval22
3  D.. A.. pval1.. pval2..

【问题讨论】:

    标签: r function for-loop


    【解决方案1】:

    与每个编程问题一样,解决方案分为两个步骤:

    1. 抽象您的逻辑以使其通用
    2. 将抽象解决方案封装成可重用函数

    你可以继续

    1. 对所有数据重复调用该函数。

    但是,首先:t 检验有时会因数据不足而失败;所以让我们替换 t.test 调用:

    t_test = function (x, y, ...) {
        tryCatch(t.test(x, y, ...)$p.value, error = function (err) NA)
    }
    

    那么,综合起来,这给了我们:

    library(dplyr) # Makes data manipulation easier.
    
    test_combination = function (data, id) {
        drug = data[id, ]$DRUG
        adr = data[id, ]$ADR
    
        match = filter(data, DRUG == drug, ADR == adr)$X
        mismatch1 = filter(data, DRUG != drug, ADR == adr)$X
        mismatch2 = filter(data, DRUG == drug, ADR != adr)$X
    
        list(pval1 = t_test(match, mismatch1), pval2 = t_test(match, mismatch2))
    }
    

    测试单个组合。现在我们测试所有这些:

    result = lapply(dat$ID, test_combination, data = dat) %>%
        bind_rows() %>%
        bind_cols(dat, .) %>%
        select(-X)
    

    或者,使用更类似于 dplyr(但在我看来有些晦涩)的方法:

    result = dat %>%
        rowwise() %>%
        do(bind_rows(test_combination(dat, .$ID))) %>%
        bind_cols(dat, .) %>%
        select(-X)
    

    请注意此代码如何不使用显式 for 循环。这就是您在 R 中处理数据的方式:您将函数应用于表或列表中的项目,而不是手动迭代。

    请注意,从统计上讲,上述内容非常值得怀疑。至少你需要执行严格的multiple testing correction

    【讨论】:

      猜你喜欢
      • 2017-11-17
      • 1970-01-01
      • 1970-01-01
      • 2018-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多