Почему мой код R работает нормально на виртуальном кластере, а не на моей физической машине? - PullRequest
0 голосов
/ 30 октября 2019

У меня просто быстрый вопрос по поводу моего кода. У меня есть некоторые расхождения между кодом, который я запускал на виртуальном кластере с запущенной RStudio, и кодом, который я запускал на своей физической машине. Нам пришлось создать файл R-Markdown, чтобы воспроизвести таблицу ANOVA. Я выполнил свой код на кластере просто отлично.

Вот мой код:

```{r, message=FALSE, warning=FALSE}
wine <- read.csv("wine.csv")

cultivar <- as.factor( wine[, "Cultivar"])
alcohol <- wine[, "Alcohol"]

alcohol.list <- split(alcohol, cultivar)


alcohol.list

$`1`
 [1] 14.23 13.20 13.16 14.37 13.24 14.20 14.39 14.06 14.83 13.86 14.10 14.12 13.75 14.75 14.38 13.63 14.30 13.83 14.19 13.64
[21] 14.06 12.93 13.71 12.85 13.50 13.05 13.39 13.30 13.87 14.02 13.73 13.58 13.68 13.76 13.51 13.48 13.28 13.05 13.07 14.22
[41] 13.56 13.41 13.88 13.24 13.05 14.21 14.38 13.90 14.10 13.94 13.05 13.83 13.82 13.77 13.74 13.56 14.22 13.29 13.72

$`2`
 [1] 12.37 12.33 12.64 13.67 12.37 12.17 12.37 13.11 12.37 13.34 12.21 12.29 13.86 13.49 12.99 11.96 11.66 13.03 11.84 12.33
[21] 12.70 12.00 12.72 12.08 13.05 11.84 12.67 12.16 11.65 11.64 12.08 12.08 12.00 12.69 12.29 11.62 12.47 11.81 12.29 12.37
[41] 12.29 12.08 12.60 12.34 11.82 12.51 12.42 12.25 12.72 12.22 11.61 11.46 12.52 11.76 11.41 12.08 11.03 11.82 12.42 12.77
[61] 12.00 11.45 11.56 12.42 13.05 11.87 12.07 12.43 11.79 12.37 12.04

$`3`
 [1] 12.86 12.88 12.81 12.70 12.51 12.60 12.25 12.53 13.49 12.84 12.93 13.36 13.52 13.62 12.25 13.16 13.88 12.87 13.32 13.08
[21] 13.50 12.79 13.11 13.23 12.58 13.17 13.84 12.45 14.34 13.48 12.36 13.69 12.85 12.96 13.78 13.73 13.45 12.82 13.58 13.40
[41] 12.20 12.77 14.16 13.71 13.40 13.27 13.17 14.13

oneway <- function(z)
  {
   ni <- sapply(z, length)
   yi_bar <- sapply(z, mean)
   s2i <- sapply(z, sd)
   Y_bar <- mean(unlist(z))
   g <- length(z)
   N <-length(unlist(z))

   Within_SS = sum((ni-1) * s2i^2)
   Between_SS = sum(ni *((yi_bar)-(Y_bar))^2)

   DF_Within = (N - g)
   DF_Between = (g - 1)

   list("WithinSS" = Within_SS, "BetweenSS"= Between_SS, "DFWithin" = DF_Within, "DFBetween" = DF_Between)

 }


 alcohol.aov <- oneway(alcohol.list)

 alcohol.aov

oneway.table <- function(z)
 {
   Mean_SSW <- z[[1]]/z[[3]]
   Mean_SSB <- z[[2]]/z[[4]]
   F_value <- (Mean_SSB/Mean_SSW)
   P_value <- pf(F_value, DF_Between, DF_Within, lower.tail = FALSE)

   anova <- matrix(c( z[[4]], z[[3]], z[[2]], z[[1]], Mean_SSB, Mean_SSW, F_value, NA, P_value, NA), ncol =5)
   dimnames(anova) <- list("Group" = c("cultivar", "Residuals"), "ANOVA" = c("DF", "Sum_Sq", "Mean_Sq", "F_value", "P_value"))

   printCoefmat(anova, signif.stars = TRUE, has.Pvalue = TRUE, digits = 3, na.print="")

 }

 oneway.table(alcohol.aov)

Код, который я прекрасно работал на виртуальном кластере, и мне удалось воспроизвести эту таблицу ANOVA:

               DF  Sum_Sq Mean_Sq F_value P_value    
cultivar    2.000  70.795  35.397     135  <2e-16 ***
Residuals 175.000  45.859   0.262                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Однако, когда я запустил его на своем локальном компьютере, я получил это сообщение об ошибке:

Error in pf(F_value, DF_Between, DF_Within, lower.tail = FALSE) : object 'DF_Between' not found

Я понимаю, что мой DF_Between не найден в моемвторой кусок кода, но почему он будет работать в кластере, а не на моей локальной машине?

Также я перезапустил свой код, на этот раз добавив определения к переменным:

oneway.table <- function(z)
 {

   g <- length(z)
   N <-length(unlist(z))

   DF_Within <- (N - g)
   DF_Between <- (g - 1)

   Mean_SSW <- z[[1]]/z[[3]]
   Mean_SSB <- z[[2]]/z[[4]]
   F_value <- (Mean_SSB/Mean_SSW)
   P_value <- pf(F_value, DF_Between, DF_Within, lower.tail = FALSE)



   anova <- matrix(c( z[[4]], z[[3]], z[[2]], z[[1]], Mean_SSB, Mean_SSW, F_value, NA, P_value, NA), ncol =5) 
   dimnames(anova) <- list("Group" = c("cultivar", "Residuals"), "ANOVA" = c("DF", "Sum_Sq", "Mean_Sq", "F_value",           "P_value")) 

   printCoefmat(anova, signif.stars = TRUE, has.Pvalue = TRUE, digits = 3, na.print="")

 }

 oneway.table(alcohol.aov)

Но теперь мой вывод выглядит следующим образом:

       ANOVA
Group            DF  Sum_Sq Mean_Sq F_value P_value
  cultivar    2.000  70.795  35.397     135        
  Residuals 175.000  45.859   0.262                

Никаких значимых звезд уровня или какого-либо P_Value. Если кто-то может помочь, это было бы очень признательно.

1 Ответ

0 голосов
/ 30 октября 2019

Решение

Вот как это можно исправить без объяснения.

Создание воспроизводимого примера:

alcohol.list <- list("1"=c(14.2, 13.2), 
                     "2"=c(12.3, 12.3),
                     "3"=c(12.8, 12.9))
alcohol.list

Ваша нетронутая oneway функция:

oneway <- function(z)
  {
   ni <- sapply(z, length)
   yi_bar <- sapply(z, mean)
   s2i <- sapply(z, sd)
   Y_bar <- mean(unlist(z))
   g <- length(z)
   N <-length(unlist(z))

   Within_SS = sum((ni-1) * s2i^2)
   Between_SS = sum(ni *((yi_bar)-(Y_bar))^2)

   DF_Within = (N - g)
   DF_Between = (g - 1)

   list("WithinSS" = Within_SS, "BetweenSS"= Between_SS, "DFWithin" = DF_Within, "DFBetween" = DF_Between)

 }


 alcohol.aov <- oneway(alcohol.list)

Наконец, ваш oneway.table с p.value:

oneway.table <- function(z)
 {
   Mean_SSW <- z$WithinSS/z$DFWithin
   Mean_SSB <- z$BetweenSS/z$DFBetween
   F_value <- (Mean_SSB/Mean_SSW)
   P_value <- pf(F_value, z$DFBetween, z$DFWithin, lower.tail = FALSE)

   anova <- matrix(c(z[[4]], z[[3]], z[[2]], z[[1]], Mean_SSB, Mean_SSW, F_value, NA, P_value, NA), ncol =5)
   dimnames(anova) <- list("Group" = c("cultivar", "Residuals"), "ANOVA" = c("DF", "Sum_Sq", "Mean_Sq", "F_value", "P_value"))

   printCoefmat(anova, signif.stars = TRUE, has.Pvalue = TRUE, digits = 3, na.print="")

 }
oneway.table(alcohol.aov)

Возвращает:

             DF Sum_Sq Mean_Sq F_value P_value  
cultivar  2.000  1.990   0.995    5.91   0.091 .
Residuals 3.000  0.505   0.168                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Объяснение

В следующем коде DF_Between не был создан до вызова метода pf(). На самом деле DF_Within также не был создан и не существует в этой области.

Это может работать, например:

# create DF_Between and DF_Within first and pass in all three as arguments
oneway.table <- function(z, DF_Between, DF_Within){
   Mean_SSW <- z[[1]]/z[[3]]
   Mean_SSB <- z[[2]]/z[[4]]
   F_value <- (Mean_SSB/Mean_SSW)
   P_value <- pf(F_value, DF_Between, DF_Within, lower.tail = FALSE)

   ...
 }

Это также может работать:

oneway.table <- function(z){
   Mean_SSW <- z[[1]]/z[[3]]
   Mean_SSB <- z[[2]]/z[[4]]
   F_value <- (Mean_SSB/Mean_SSW)
   # provided that z is a list with the two elements
   P_value <- pf(F_value, z$DF_Between, z$DF_Within, lower.tail = FALSE)

   ...
 }

Это также работает:

oneway.table <- function(z){
   Mean_SSW <- z[[1]]/z[[3]]
   Mean_SSB <- z[[2]]/z[[4]]
   F_value <- (Mean_SSB/Mean_SSW)
   # create DF_Between and DF_Within directly in here
   g <- length(z)
   N <-length(unlist(z))
   DF_Within <- (N - g)
   DF_Between <- (g - 1)
   P_value <- pf(F_value, DF_Between, DF_Within, lower.tail = FALSE)

   ...
 }

В зависимости от способаВы выбрали, вам просто нужно понять лексические рамки правила, которые использует R. Спасая вас от длинного и утомительного объяснения, вот как это происходит:

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

  • Если значениеЕсли символ не найден в среде, в которой была определена функция, то поиск продолжается в родительской среде.
  • Поиск продолжается в последовательности родительских сред, пока мы не достигнем среды верхнего уровня;обычно это глобальная среда (рабочее пространство) или пространство имен пакета.
  • После среды верхнего уровня поиск продолжается вниз по списку поиска, пока мы не попадем в пустую среду.

В среде вашего локального компьютера сначала выполняется поискдля DF_Between и DF_Within в среде, в которой была определена эта функция, oneway.table. Там он не был найден, поэтому в родительской среде ищутся DF_Between и DF_Within, и там он также не был найден, и он попадает в пустую среду.

Но в вашем кластере он сначала ищет DF_Between и DF_Within в среде, в которой была определена эта функция, oneway.table. Там он не был найден, поэтому DF_Between и DF_Within ищутся в родительской среде, и там он был найден. Так что никаких ошибок или исключений не возникло.

Вы можете подтвердить это, запустив ls(), чтобы напечатать и убедиться, что DF_Within и DF_Between действительно существовали в родительской среде в кластере, а не на локальном компьютере. ,

...