R для цикла с парными переменными

Я новичок в программировании (т. Е. С циклами и операторами 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

person M. 0.    schedule 24.06.2017    source источник


Ответы (3)


Я не уверен, какой формат вы хотите получить.

Что-то вроде этого вернет список

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
})
person mr.joshuagordon    schedule 24.06.2017
comment
Это сработало! В итоговом выходном списке результатов t-теста не указывается рассматриваемая характеристика: data: male[[trait]] and female[[trait]] используется для каждого результата теста. Я предполагаю, что из-за того, как цикл настроен и называет каждый признак, нет способа включить рассматриваемый признак в список результатов t-теста? - person M. 0.; 25.06.2017
comment
Потому что у меня разное количество самцов и самок: Error in data.frame(male[[trait]], female[[trait]]) : arguments imply differing number of rows: 150, 114 - person M. 0.; 25.06.2017
comment
В ПОРЯДКЕ. просто напишите имена прямо тогда. Это работает, но некрасиво - person mr.joshuagordon; 25.06.2017

Извините, если вы неправильно истолковали ваш вопрос, мне кажется, что вы просто пытаетесь применить цикл к своему первому выражению 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.

person Dan Woodrich    schedule 24.06.2017

Возьмите функцию и используйте purrr:map() или purrr:map2(), которые будут перебирать каждое значение через функцию.

person Mako212    schedule 25.06.2017