簡體   English   中英

我可以從名稱列表中創建新的xts列嗎?

[英]Can I create new xts columns from a list of names?

我的目標是:從yahoo讀取數據文件,然后使用列表在每個xts上執行計算,以創建xts的名稱和將結果分配到的列的名稱。

為什么? 我想對大量xts數據集執行相同的計算,而不必重新鍵入單獨的行以對每個數據集執行相同的計算。

首先,獲取2個ETF的數據集:

library(quantmod)
# get ETF data sets for example
startDate = as.Date("2013-12-15") #Specify period of time we are interested in
endDate = as.Date("2013-12-31")
etfList <- c("IEF","SPY")
getSymbols(etfList, src = "yahoo", from = startDate, to = endDate)

為了簡化編碼,請更換ETF。 雅虎數據的前綴

colnames(IEF) <- gsub("SPY.","", colnames(SPY))
colnames(IEF) <- gsub("IEF.","", colnames(IEF))
head(IEF,2)
             Open   High    Low  Close Volume Adjusted
#2013-12-16 100.86 100.87 100.52 100.61 572400    98.36
#2013-12-17 100.60 100.93 100.60 100.93 694800    98.67

使用Quantmod中的函數創建新列非常簡單,例如,

SPY$logRtn <- periodReturn(Ad(SPY),period='daily',subset=NULL,type='log')
IEF$logRtn <- periodReturn(Ad(IEF),period='daily',subset=NULL,type='log')
head(IEF,2)
#              Open   High    Low  Close Volume Adjusted    logRtn
#2013-12-16 100.86 100.87 100.52 100.61 572400    98.36 0.0000000
#2013-12-17 100.60 100.93 100.60 100.93 694800    98.67 0.0031467

但是,我想創建一個新的語句來執行每個ETF的計算,而不是使用一個列表。 這是一般的想法:

etfList
#[1] "IEF" "SPY"
etfColName = "logRtn"

for (etfName in etfList) {
    newCol <- paste(etfName, etfColName, sep = "$"
    newcol <- periodReturn(Ad(etfName),period='daily',subset=NULL,type='log')
}

當然,使用字符串(顯然)不起作用,因為

typeof(newCol) # is [1] "character"
typeof(logRtn) # is [1] "double"

我已經嘗試了所有我能想到的一切(至少兩次),將字符串etfName $ etfColName強制轉換為可以分配計算結果的對象。

我看過許多與data.frames兼容的變體,例如dplyr的mutate(),但不適用於xts數據文件。 我可以將數據集從xts向前/向后轉換為data.frames,但這是相當麻煩的(至少可以這樣說)。

那么,有人可以提出一個優雅而直接的解決方案(即,用不到25行代碼)嗎?

我將非常感激,以至於當我有足夠的能力購買我自己的NFL球隊時,您總會在所有者的信箱中占有一席之地。

如果您將數據存儲在新環境中,則這種類型的任務會容易得多。 然后,您可以使用eapply遍歷環境中的所有對象並將功能應用到它們。

library(quantmod)
etfList <- c("IEF","SPY")

# new environment to store data
etfEnv <- new.env()
# use env arg to make getSymbols load the data to the new environment
getSymbols(etfList, from="2013-12-15", to="2013-12-31", env=etfEnv)

# function containing stuff you want to do to each instrument
etfTransform <- function(x, ...) {
  # remove instrument name prefix from colnames
  colnames(x) <- gsub(".*\\.", "", colnames(x))
  # add return column
  x$logRtn <- periodReturn(Ad(x), ...)
  x
}
# use eapply to apply your function to each instrument
etfData <- eapply(etfEnv, etfTransform, period='daily', type='log')

(我沒有意識到您發布了可復制的示例。)

看看這是否有幫助:

 etfColName = "logRtn"
 for ( etfName in etfList ) {
     newCol <- get(etfName)[ ,  etfColName]
     assign(etfName, cbind( get(etfName), 
                            periodReturn( Ad(get(etfName)), 
                                          period='daily', 
                                         subset=NULL,type='log')))
                        }

> names(SPY)
[1] "SPY.Open"      "SPY.High"      "SPY.Low"       "SPY.Close"    
[5] "SPY.Volume"    "SPY.Adjusted"  "logRtn"        "daily.returns"

我不是Quantmod用戶,僅是從我看到的行為來看,我相信Ad函數返回命名向量。 (因此,我不需要進行任何命名。)

R不是宏語言,這意味着您不能僅將字符值串在一起並期望它們像在命令行中鍵入它們一樣被執行。 getassign函數允許您基於字符值從數據對象環境中“拉”和“推”項目,但是您不應將$ -函數與它們結合使用。

我仍然看不到newCol的創建與您的代碼試圖創建的實際新列之間的聯系。 他們有不同的拼寫,所以本來會在不同的專欄...如果我能弄清您的嘗試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM