Один и тот же код в разных средах дает разные результаты в R

#r

Вопрос:

Следующий код отображает определенный ответ на запрос:

 library(quantmod)

# Load ticker data from 2020-01-01 till 2021-02-02
t <- c("NKLA", "MPNGF", "RMO", "JD", "MSFT")
getSymbols.yahoo(t, auto.assign = TRUE, env = globalenv(), 
                 from = "2020-01-01", to = "2021-02-02")

# Close all Internet connections as a precaution
closeAllConnections()

# Find xts objects
x <- names(which(unlist(eapply(.GlobalEnv, is.xts))))

# Convert xts to data.frame
for (i in seq_along(x)) {
  assign(x[i], fortify.zoo(get(x[i])))
}

# The query
sapply(mget(x), names)

# The rendering
     NKLA            MPNGF            MSFT            JD            RMO           
[1,] "Index"         "Index"          "Index"         "Index"       "Index"       
[2,] "NKLA.Open"     "MPNGF.Open"     "MSFT.Open"     "JD.Open"     "RMO.Open"    
[3,] "NKLA.High"     "MPNGF.High"     "MSFT.High"     "JD.High"     "RMO.High"    
[4,] "NKLA.Low"      "MPNGF.Low"      "MSFT.Low"      "JD.Low"      "RMO.Low"     
[5,] "NKLA.Close"    "MPNGF.Close"    "MSFT.Close"    "JD.Close"    "RMO.Close"   
[6,] "NKLA.Volume"   "MPNGF.Volume"   "MSFT.Volume"   "JD.Volume"   "RMO.Volume"  
[7,] "NKLA.Adjusted" "MPNGF.Adjusted" "MSFT.Adjusted" "JD.Adjusted" "RMO.Adjusted"
 

Один и тот же код, адаптированный под конкретную среду:

 library(quantmod)

symbolUpdates.env <- new.env()

# Load ticker data from 2020-01-01 till 2021-02-02 to symbolUpdates.env
t2 <- c("NKLA", "MPNGF", "RMO", "JD", "MSFT")
getSymbols.yahoo(t2, auto.assign = TRUE, env = symbolUpdates.env, 
                 from = "2020-01-01", to = "2021-02-02")

# Close all Internet connections as a precaution
closeAllConnections()

# Find xts objects in symbolUpdates.env
x2 <- names(which(unlist(eapply(symbolUpdates.env, is.xts))))

# Convert xts to data.frame that are in symbolUpdates.env
for (i2 in seq_along(x2)) {
  assign(envir = symbolUpdates.env, x2[i], fortify.zoo(get(x2[i2])))
}

# The query in symbolUpdates.env
sapply(mget(x2, envir = symbolUpdates.env), names)

# The rendering from symbolUpdates.env
     RMO            NKLA            JD            MSFT            MPNGF           
[1,] "Index"        "Index"         "Index"       "Index"         "Index"         
[2,] "Index"        "Index"         "Index"       "Index"         "Index"         
[3,] "RMO.Open"     "NKLA.Open"     "JD.Open"     "MSFT.Open"     "MPNGF.Open"    
[4,] "RMO.High"     "NKLA.High"     "JD.High"     "MSFT.High"     "MPNGF.High"    
[5,] "RMO.Low"      "NKLA.Low"      "JD.Low"      "MSFT.Low"      "MPNGF.Low"     
[6,] "RMO.Close"    "NKLA.Close"    "JD.Close"    "MSFT.Close"    "MPNGF.Close"   
[7,] "RMO.Volume"   "NKLA.Volume"   "JD.Volume"   "MSFT.Volume"   "MPNGF.Volume"  
[8,] "RMO.Adjusted" "NKLA.Adjusted" "JD.Adjusted" "MSFT.Adjusted" "MPNGF.Adjusted"
 

Мои вопросы:

  • Есть ли какие-либо ошибки в коде, в котором появляется дополнительный Index столбец symbolUpdates.env ?
  • Если да, то что это такое?
  • Что могло бы исправить эту проблему?
  • Кроме того, порядок тикеров не соблюдается symbolUpdates.env , почему?

Заранее спасибо.


Используемые системы:

  • Версия R: 4.1.1 (2021-08-10)
  • Версия RStudio: 1.4.1717
  • ОС: macOS Catalina версии 10.15.7 и macOS Big Sur версии 11.6

Комментарии:

1. Не было бы намного проще и чище просто использовать (именованные)списки вместо assign и сред ?

2. Одна ошибка во второй версии заключается в get() вызове: get(x2[i])) по умолчанию используется глобальная среда, а не symbolUpdates.env .

3. @user2554330, спасибо за ваш комментарий. Я исправил ошибку в посте. Я тоже это R сделал, но проблема не устранена: у меня все еще есть 2 Index столбца.

4. @дарио. Это возможно, однако я понятия не имею, как это сделать. Не могли бы вы показать, как это делается?

5. Вот как мы присваиваем значение именованному списку в R: new_list <- list(); new_list[["new_element"]] <- "new_element_value" .

Ответ №1:

Заказ можно оформить с match помощью, и для меня я не получаю никакой дополнительной Index колонки.

 lapply(mget(x2, envir = symbolUpdates.env), names)
data <- mget(x2[match(t2, x2)], envir = symbolUpdates.env)
sapply(data, names)

#      NKLA            MPNGF            RMO            JD            MSFT           
#[1,] "NKLA.Open"     "MPNGF.Open"     "RMO.Open"     "JD.Open"     "MSFT.Open"    
#[2,] "NKLA.High"     "MPNGF.High"     "RMO.High"     "JD.High"     "MSFT.High"    
#[3,] "NKLA.Low"      "MPNGF.Low"      "RMO.Low"      "JD.Low"      "MSFT.Low"     
#[4,] "NKLA.Close"    "MPNGF.Close"    "RMO.Close"    "JD.Close"    "MSFT.Close"   
#[5,] "NKLA.Volume"   "MPNGF.Volume"   "RMO.Volume"   "JD.Volume"   "MSFT.Volume"  
#[6,] "NKLA.Adjusted" "MPNGF.Adjusted" "RMO.Adjusted" "JD.Adjusted" "MSFT.Adjusted"
 

Комментарии:

1. Я думаю, что необходимо (не уверен, что это верно/необходимо), чтобы порядок содержимого symbolUpdates.env соответствовал порядку содержимого .GlobalEnv (т. Е. symbolUpdates.env Порядок содержимого = RMO NKLA JD MSFT MPNGF , тогда .GlobalEnv как порядок содержимого = MSFT MPNGF NKLA JD RMO ).

2. Тем не менее, identical(names(x), names(x2)) визуализация TRUE , так что я думаю data.frame , что порядок объектов в разных environment s не должен быть проблемой для добавления одного к другому. Я прав? Тем не менее, identical(x, x2) рендеры FALSE

Ответ №2:

@user2554330 указал на ошибку в кодировании и отсутствие фрагмента. Исправление первого и добавление второго сделали свое дело.

Вот как выглядел исходный код последнего for цикла:

 for (i2 in seq_along(x2)) {
  assign(envir = symbolUpdates.env, x2[i], fortify.zoo(get(x2[i])))
}
 

Вот как это должно было выглядеть ( i2 вместо i и добавление envir = symbolUpdates.env в конце:

 for (i2 in seq_along(x2)) {
  assign(envir = symbolUpdates.env, x2[i2], fortify.zoo(get(x2[i2], 
                                           envir = symbolUpdates.env)))
}