簡體   English   中英

有人可以幫我清理我的功能嗎?

[英]Can someone help me clean up my r function?

這是我關於編程的第一篇文章,所以如果我沒有使用正確的術語或在正確的位置發布,我會道歉。 我對使用r非常陌生,而且對編程很新(除了一點點VBA)。 我寫了一個基本函數,用於計算從最新價格到最早價格列出的股票價格列表的每日價格回報。 我認為我的代碼有點草率,我可以使用一些幫助來清理它。 我創建“returnarray”的目的是讓我可以將循環結果存儲到變量而不是僅僅打印。

我真的想在這里做的一件事是消除對“returnarray”的需要,而是希望將結果保存到用戶輸入的任何內容中。 例如, myreturns <- price.return(mydata)將生成一個名為myreturns的變量,其中包含所有返回,而不是創建returnarray。 在下面找到我的代碼,並提前感謝您。

    price.return <- function(mydata)
{
  returnarray <- c()
  tmp <- c()
  for (i in 1:length(mydata)-1)

  {
   tmp <- (((mydata[i]/mydata[i+1])-1))
   returnarray <- c(returnarray,tmp)
   returnarray <<- returnarray
  }

}

從評論中轉移。

1)問題中顯示的功能是這樣的:

price.return1 <- function(x) x[-length(x)] / x[-1] - 1  # similar to question

2)索引在時間上增加似乎問題是假設x[1]是最近的點而x[length(x)]是最舊的點,而正常的約定是x[1]是最老的點並且x[length(n)]是最新的,即通常假設索引在時間上增加,因此使用這個更常見的約定它將被寫成如下:

price.return2 <- function(x) x[-1] / x[-length(x)] - 1 # assume index increasing in time

示例:為了舉例說明price.return2 ,假設價格隨時間增加1,2,3,4,5。 然后我們可以寫:

price.return2(1:5)
## [1] 1.0000000 0.5000000 0.3333333 0.2500000

所以從1到2的回報是1或100%,從2到3的回報是.5或50%,依此類推。

3)相同寫一個等價於price.return2的替代方法是:

price.return3 <- function(x) exp(diff(log(x))) - 1  # similar to price.return2

我們可以驗證price.return2price.return3給出輸入1:5類似答案,如下所示:

all.equal(price.return2(1:5), price.return3(1:5))
## [1] TRUE

注意:您可能對動物園中的一些函數感興趣,xts,PerformanceAnalytics和quantmod包。 更多信息,請參閱“ 經驗財務任務視圖”

有人可能會提供更清潔的解決方案,但希望這至少有點用處:

price.return <- function(mydata) {
  for (i in 1:length(mydata)-1) {
    mydata[i] <- mydata[i] / mydata[i+1] - 1
  }
  return(mydata[1:(length(mydata) - 1)])
}
  1. 主要的是使用return()在函數末尾返回一個值 - 這將阻止你需要創建returnarray()。
  2. 我不認為你需要初始化你的變量,雖然肯定沒有壞處,這可能是一個好習慣。

你應該開始習慣的一件事是矢量化。 R編程的本質是使用已經構建的函數來進行矢量化以幫助您。 R中的for循環並不總是最好的選擇,特別是如果你可以使用向量。

此外,您通常應該提供可以輕松復制的數據,以便其他人可以將您的結果與您進行比較。

好吧,歡迎來到R,這是一個更有效的解決方案:

### always have replicable data at the beginning of your question
### this allows answers to verify that they are indeed doing what you want them to do
data <- data.frame(c(120.663499,122.047573,121.480003,
                     120.919998,121.059998,120.57,116.769997))
rownames(data) <- rev(seq(as.Date("2015/11/05"),as.Date("2015/11/11"),"days"))
colnames(data) <- "AAPL"

> data
               AAPL
2015-11-11 120.6635
2015-11-10 122.0476
2015-11-09 121.4800
2015-11-08 120.9200
2015-11-07 121.0600
2015-11-06 120.5700
2015-11-05 116.7700

### since your data is from newest to oldest, I have to switch them to oldest to newest
### this is the common convention used in finance. Also, packages like quantmod do this
### you can collect price data very quickly using quantmod

### its important to use rownames(data) that way the associated date stays with the price
data <- data[rev(rownames(data)),,drop=F]

> data
               AAPL
2015-11-05 116.7700
2015-11-06 120.5700
2015-11-07 121.0600
2015-11-08 120.9200
2015-11-09 121.4800
2015-11-10 122.0476
2015-11-11 120.6635

### we use the vectorized diff() function to calculate the difference between
### each consecutive price (Pt - Pt-1)
### we then divide that difference by the previous period's price
### in notation: (Pt-Pt-1)/Pt-1
res <- diff(data$AAPL)/data$AAPL[-length(data$AAPL)]

### Now I am just putting this in the data frame to show you how it might look
### in something in excel
res <- data.frame(data,"Returns"=c(NA,res))

我希望這有幫助。 如果你想繼續在R中用金融價格做這種工作,我強烈建議你學習以類似的方式編寫代碼。 矢量化非常重要。 For循環通常是您想要使用的最后一件事。 隨着數據集越來越大,代碼的速度會呈指數級增長。

暫無
暫無

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

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