Как написать функцию, которая отклоняет Z-оценку в R?

Как я могу написать функцию, которая возвращает «отклонить», когда zscore>=qnorm(1-alpha/2) для 10 симуляций для alpha=0,05 и размера выборки 10. Я написал следующий код, но я не получаю корректный вывод. «zscore» — это статистика теста, а t является нормальным со средним значением и стандартным отклонением 6/n. sims соответствует количеству выполняемых симуляций. Эта функция должна имитировать оценку методом Монте-Карло.

testsk=function(n,alph,sims){
    t=numeric(sims)
for (i in 1:sims) {
    x=rnorm(n)
t[i]=skewness(x)
zscore=t/(6/n)
return(zscore)
}
if(zscore>=qnorm(1-alph/2)){
print("REJECT")
}
}


testsk(10,0.05,10)

Спасибо!


person user3347124    schedule 01.04.2014    source источник
comment
У вас слишком много '}'. Получите настоящий редактор кода, чтобы избежать подобных ошибок (например, rstudio).   -  person Jealie    schedule 02.04.2014
comment
мне непонятно, чего вы пытаетесь достичь. Я вижу, что вы пытаетесь неоднократно брать наборы n выборок из стандартного нормального распределения и вычислять асимметрию каждого набора, сохраняя асимметрию набора i в t[i]. Но что такое z-оценка? Это должна быть векторная или скалярная величина, и как вы ее определяете? В любом случае я не вижу смысла return делать это из середины вашего for цикла, как вы это делаете сейчас.   -  person TooTone    schedule 02.04.2014


Ответы (3)


Я полагаю, что после вашего редактирования вы хотите увидеть, сколько раз за sims испытаний асимметрия, рассчитанная на основе выборки размером n, взятой из нормального распределения, будет отклонена как слишком искаженная критерием значимости на уровне alph.

У вас есть несколько проблем с кодированием

  1. Вы хотите выполнить тест z-счета для каждого испытания, но тест находится вне цикла.
  2. Показатель z рассчитывается с использованием вектора t, но вы хотите вычислить его с помощью скаляра t[i].
  3. Внутри цикла есть оператор return, который заставит функцию завершиться на первой итерации цикла, возвращая оценку z. По причине № 2 показатель z представляет собой вектор, но все его предпоследние значения равны нулю, поскольку вы выполнили только одну итерацию, поэтому типичный вывод функции выглядит следующим образом.

    0.003623371 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000

Исправление этих непосредственных проблем приводит к следующему коду

library(e1071)
testsk=function(n,alph,sims) {
    t=numeric(sims)
    for (i in 1:sims) {
        x=rnorm(n)
        t[i]=skewness(x)
        zscore=t[i]/(6/n)
        if(zscore>=qnorm(1-alph/2)){
            print("REJECT")
        }
    }
}

Однако этот стиль все еще страдает от некоторых проблем:

  1. From a programming point of view
    • printing out "REJECT" gives immediate feedback but isn't very scalable. If you had sims=1000 you would be better off returning the number of rejects, nr. And if you still wanted to print out "REJECT" nr times you could do so :)
    • Также код мог бы быть проще и написан в стиле R, с векторизацией, а не с использованием циклов. Это также имело бы то преимущество, что было бы намного быстрее. Поскольку R является интерпретируемым языком, векторизация имеет огромное значение, потому что обработка чисел может происходить под капотом, и R не нужно снова и снова проходить цикл for.
  2. Perhaps more seriously, there are some statistical problems:
    • 6/n is an estimate of the variance of the skewness (wikipedia), but you want the standard deviation so you need to take the square root of 6/n.
    • Код отклоняется, если показатель z больше 1-alph/2го квантиля, но он также должен отклоняться, если показатель z меньше alph/2го квантиля. В нынешнем виде ваш регион отклонения alph/2, а не alph.
    • Могут быть и другие проблемы, но эти, на мой взгляд, основные. (Я предполагаю, что вы знаете, что 6/n — это только хорошая оценка дисперсии для больших выборок.)

Программа, которая находится в правильном направлении, выглядит следующим образом

library(e1071)
testsk=function(n,alph,sims) {
    # Generate random numbers in a matrix, each trial is a row
    X=matrix(rnorm(sims*n), ncol=n)
    # Get skewnesses, 1 means apply to rows
    skews=apply(X,1,skewness)
    # Calculate z score vector and rejection vector
    zscore=skews/sqrt(6/n)
    reject=!(qnorm(alph/2) < zscore & zscore < qnorm(1-alph/2))
    # Return the number of rejections
    sum(reject)
}

Вы должны быть в состоянии изменить его в соответствии с вашими целями, но я могу уточнить, если необходимо.

person TooTone    schedule 01.04.2014

Не уверен, чего вы пытаетесь достичь, но вот один из способов сделать это

testsk <- function(n, alph, sims){
  for (i in 1:sims){
  x <- rnorm(n)
  zscore <- skewness(x)/(6/n)
  cat(paste0("Simulation #", i,":"), ifelse(zscore >= qnorm(1 - alph/2), "REJECT", "Don't REJECT"), "\n")
  }
}

n <- 10
alph <- .05
sims <- 10
testsk(n, alph, sims)

#Simulation #1: Don't REJECT 
#Simulation #2: REJECT 
#Simulation #3: Don't REJECT 
#Simulation #4: Don't REJECT 
#Simulation #5: Don't REJECT 
#Simulation #6: Don't REJECT 
#Simulation #7: Don't REJECT 
#Simulation #8: Don't REJECT 
#Simulation #9: Don't REJECT 
#Simulation #10: Don't REJECT 
person David Arenburg    schedule 01.04.2014

Вы неправильно перебираете sims. Можете ли вы объяснить, что вы пытаетесь сделать?

testsk <- function(n,alph,sims) {
  t <- numeric(sims)
  for (i in seq_along(sims)) {
    x <- rnorm(n)
    t[i] <- skewness(x)
  }
  zscore <- t/(6/n)
  if (any(zscore>=qnorm(1-alph/2))) {
    print("REJECT")
  }
  return(zscore)
}

testsk(10,0.05,10)
person Robert Krzyzanowski    schedule 01.04.2014
comment
Я не уверен насчет seq_along(sims). Переменная sims является скалярной, и исходная 1:sims выглядит лучше. - person TooTone; 02.04.2014