состояние в цикле в R - PullRequest
0 голосов
/ 04 марта 2019

У меня есть относительно простой вопрос, для которого я не смог применить решения, которые я нашел в Интернете.Допустим, у нас есть:

set.seed(20)

data <- data.frame(month = rep(month.name, 25), 
a = rnorm(300, 0, 1), b = runif(300, 0, 7.2))

Я хочу вычислить с помощью цикла f-критерий для дисперсии между столбцами a и b для каждого месяца в месяц .Это я сделал с помощью:

# create some empty vectors to fill in later
pval <- as.double()
ftest <- as.double()
month <- as.character()

# looping through the months

for (i in unique(data$month)){
  print(i)
  # sh.1 <- shapiro.test(data$a[data$month==i])
  # sh.1[2] > 0.05 # apply log if it's smaller than 0.05
  # sh.2 <- shapiro.test(data$b[data$month==i])
  # sh.2[2] > 0.05 # apply log if it's smaller than 0.05
  var.t <- var.test(data$a[data$month==i], data$b[data$month==i])
  f <- round(var.t[[1]],2)
  p <- round(var.t$p.value,2)
  ftest <- append(ftest, f)
  pval <- append(pval, p)
  month <- append(month, i)
}

Однако, насколько я знаю, f-тест очень чувствителен к нормальному распределению.Поэтому я планирую использовать условие в цикле, где в случае, если значение p теста Шапиро меньше 0,05, потребуется преобразование log для данных;тогда он будет использован в f-тесте.

Обычно я бы поступил так с условием ifelse, но я не очень уверен, как его использовать здесь.Любая помощь здесь, пожалуйста?

1 Ответ

0 голосов
/ 04 марта 2019

Я думаю, что код ниже делает то, что вы хотите.Он использует циклы *apply, а не for, чтобы сделать код более читабельным (я думаю).

Сначала я воссоздаю данные и проверяю, все ли столбцы a положительны.

set.seed(20)

data <- data.frame(month = rep(month.name, 25), 
                   a = rnorm(300, 0, 1), b = runif(300, 0, 7.2))

data$a <- abs(data$a)

Теперь, вместо циклического просмотра уникальных значений month, я разделяю данные.кадр этой переменной.Таким образом, каждый из df в результирующем списке sp уже является df всех строк каждого месяца.

sp <- split(data, data$month)
sp <- sp[order(order(month.name))]

Именно здесь данные log преобразуются при необходимости.

sp <- lapply(sp, function(DF){
  if(shapiro.test(DF[["a"]])$p.value < 0.05) DF[["a"]] <- log(DF[["a"]])
  if(shapiro.test(DF[["b"]])$p.value < 0.05) DF[["b"]] <- log(DF[["b"]])
  DF
})

И lapply тест, который вы хотите, var.test, для всех этих фреймов данных.

vartest_list <- lapply(sp, function(DF){
  var.t <- var.test(DF[["a"]], DF[["b"]])
  list(f = var.t[[1]], 
       p.value = var.t$p.value, 
       month = as.character(DF[["month"]][1]))
})

Наконец, это простой вопрос применения функции извлечения [[к результатам испытаний.Это работает, потому что функции проверки гипотез в R возвращают объекты класса "htest", которые являются ничем иным, как списками.Последний цикл извлечения закомментирован.

ftest <- sapply(vartest_list, '[[', 'f')
pval <- sapply(vartest_list, '[[', 'p.value')
#month <- sapply(vartest_list, '[[', 'month')
...