【问题标题】:R for loop with paired variablesR for循环与成对变量
【发布时间】:2017-11-28 03:30:21
【问题描述】:

我是编程新手(即循环和 if-else 语句),但对 R 中的统计数据并不陌生。

我有大约 16 个特征要在 5 个不同人群中的男性和女性之间进行比较,因此是 5x16 比较。我首先要检查男性和女性特征方差是否相等(var.test),然后使用此信息来确定 t.test 函数的正确版本(var = T 或 var = F)。我正在尝试编写一个循环来自动化这个过程。

我写了一个有效的 if-else 语句:

 if ((var.test(male$mass,female$mass)$p.value < 0.05) == "TRUE") {
   t.test(male$mass,female$mass, var = F)
 } else 
   t.test(male$mass,female$mass, var = T)

但我似乎无法弄清楚如何将其应用于我的所有特征。

我不想使用两个嵌套的 for 语句:

 for (i in c(male$trait1, male$trait2,...)) {
 for (j in c(female$trait1, female$trait2,...)) {
  ...
   }
 }

因为这会创建一个矩阵,对所有特征组合执行 var.test 和 t.test。然而,我只希望每个特征的男性和女性版本配对。

这是我的数据格式。我制作了两个数据子集(男性和女性):

head(male)
id location  gens log.gens   sex   mass   head   cbl
49   Hawaii   268 2.428135     M 583.86 78.648 65.54           
27   Hawaii   268 2.428135     M 692.30 83.604 69.67
33   Hawaii   268 2.428135     M 647.70 81.180 67.65
34   Hawaii   268 2.428135     M 704.70 84.720 70.60
35   Hawaii   268 2.428135     M 604.90 82.440 68.70

【问题讨论】:

    标签: r loops t-test


    【解决方案1】:

    我不确定您希望获得的格式。

    这样的东西会返回一个列表

    listOfTraits <- c('mass', 'head', 'cbl')
    resultList <- lapply(listOfTraits, FUN = function(trait) {
      if (var.test(male[[trait]],female[[trait]])$p.value < 0.05) {
       t.test(male[[trait]],female[[trait]], var = F)
      } else{
       t.test(male[[trait]],female[[trait]], var = T)
      }
    })
    

    第二次修复

    listOfTraits <- c('mass', 'head', 'cbl')
    resultList <- lapply(listOfTraits, FUN = function(trait) {
      if (var.test(male[[trait]],female[[trait]])$p.value < 0.05) {
        x <-  t.test(male[[trait]],female[[trait]], var = T)
        names(x$estimate) <- c(paste0('male_',trait),paste0('female_',trait))
        x$data.name <- paste0('male_',trait, " and ",paste0('female_',trait))
    
      } else{
        x <- t.test(male[[trait]],female[[trait]], var = T)
        names(x$estimate) <- c(paste0('male_',trait),paste0('female_',trait))
        x$data.name <- paste0('male_',trait, " and ",paste0('female_',trait))
      }
      x
    })
    

    【讨论】:

    • 这成功了! t 检验结果的结果输出列表未命名相关特征:data: male[[trait]] and female[[trait]] 用于每个测试结果。我猜是因为循环的设置方式并将每个特征命名为“特征”,没有办法将相关特征包含在 t 检验结果列表中?
    • 因为我的男女人数不同:Error in data.frame(male[[trait]], female[[trait]]) : arguments imply differing number of rows: 150, 114
    • 好的。直接写名字就行了。这“有效”但很丑
    【解决方案2】:

    抱歉,如果误解了您的问题,在我看来,您只是想对您的第一个 if-else 语句应用一个循环,这样它就会像质量一样循环遍历所有特征?要引用循环中的列名,您需要使用通用符号来引用列:data["numeric row","numeric column"] 而不是 data$"column name"。

    #cycles through a vector comprised of 1 through the number of columns of the data (assuming the number of traits for each sex is equal). 
    for(i in 1:length(male)){
    
    #your if-else, refering to columns with row/column notation. 
     if ((var.test(male[,i],female[,i])$p.value < 0.05) == "TRUE") {
       t.test(male[,i],female[,i], var = F)
     } else {
       t.test(male[,i],female[,i], var = T)
    }
    

    这会将这个 if-else 应用于所有特征。请注意,这不会存储 t.test 函数的结果。

    【讨论】:

    • Error in is.finite(x): default method not implemented for type 'list'
    【解决方案3】:

    获取函数并使用purrr:map() 或purrr:map2() 将通过函数迭代每个值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-15
      • 2018-02-18
      • 2016-01-18
      • 1970-01-01
      • 1970-01-01
      • 2020-05-15
      • 1970-01-01
      相关资源
      最近更新 更多