首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解一行R代码

理解一行R代码
EN

Stack Overflow用户
提问于 2017-04-02 00:17:25
回答 1查看 75关注 0票数 0

有一篇关于R博客作者如何将R中的股票价格转化为回报的博文。它将将第一行转换为1,然后跟踪前进的返回。所以他们有一个股票数据的例子:

代码语言:javascript
复制
##            AAPL.Close MSFT.Close GOOG.Close
## 2016-01-04     105.35      54.80     741.84
## 2016-01-05     102.71      55.05     742.58
## 2016-01-06     100.70      54.05     743.62
## 2016-01-07      96.45      52.17     726.39
## 2016-01-08      96.96      52.33     714.47
## 2016-01-11      98.53      52.30     716.03

当加载库magittr (显然是用于“管道”操作符)并运行以下代码时:

代码语言:javascript
复制
stock_return <- apply(stocks, 1, function(x) {x / stocks[1,]}) %>% t %>% as.xts

你明白这个:

代码语言:javascript
复制
           AAPL.Close MSFT.Close GOOG.Close
2016-01-04  1.0000000  1.0000000  1.0000000
2016-01-05  0.9749407  1.0045620  1.0009975
2016-01-06  0.9558614  0.9863139  1.0023994
2016-01-07  0.9155197  0.9520073  0.9791734
2016-01-08  0.9203607  0.9549271  0.9631052
2016-01-11  0.9352634  0.9543796  0.9652081

我不明白这行代码是如何工作的。我知道apply函数将对每一行进行操作(参数1实现了这一点)。我知道,理论上,我希望将第一行除以1(这将为该行提供1),然后将后续的每一行除以第一行,这将显示1.00投资随时间的变化。

因此,代码的这一部分是函数:

代码语言:javascript
复制
{x / stocks[1,]}) %>% t %>% 

它与一个“管道操作员”和操作从左到右而不是向外工作有关。有人能帮助我理解这个函数的语法以及它是如何完成它应该完成的任务吗?我可以用它,但我不想让它成为黑匣子。谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-02 11:53:55

首先要注意的是,只有输入是矩阵时,此代码才能工作。为了使它在数据中可重复阅读如下:

代码语言:javascript
复制
library(magrittr)
library(xts)
df <- read.table(text =" ,AAPL.Close, MSFT.Close, GOOG.Close
            2016-01-04,     105.35,      54.80,     741.84
            2016-01-05,     102.71,      55.05,     742.58
            2016-01-06,     100.70,      54.05,     743.62
            2016-01-07,      96.45,      52.17,     726.39
            2016-01-08,      96.96,      52.33,     714.47
            2016-01-11,      98.53,      52.30,     716.03", 
            sep = ",", header = TRUE, row.names = 1)
stock <- as.matrix(df)

如果你很难立刻理解整个管道是如何工作的,只需将其分成几个部分即可。

第一部分是apply函数。

代码语言:javascript
复制
apply(df, 1, function(x) {x / df[1,]})

正如您正确地指出的,它适用于矩阵的行,意思是

它将每一行martix分别传递给提供的函数(实际上在后台有一个for循环)。函数的一个简单例子是mean

代码语言:javascript
复制
apply(stock, 1, mean)

这将简单地计算每一行的平均值。这个博客的作者做了一些更复杂的事情,并提供了匿名函数(一个为这个特殊任务编写的函数) function(x) {x / stock[1,]}

因此,矩阵的每一行都作为第一个参数传递给所提供的函数。该函数只有一个参数x。因此,您可以将x看作表示原始矩阵的一行的向量。要了解该函数正在做什么,请查看它的主体x / stock[1,]

x表示原始矩阵的一行,stock[1, ]表示原始矩阵的第一行。因此,矩阵的每一行依次被矩阵的第一行划分,结果作为列添加到一个新的矩阵中,如下所示

代码语言:javascript
复制
                       2016-01-04             2016-01-05             2016-01-06
AAPL.Close                      1              0.9749407              0.9558614
MSFT.Close                      1              1.0045620              0.9863139
GOOG.Close                      1              1.0009975              1.0023994
                       2016-01-07             2016-01-08             2016-01-11
AAPL.Close              0.9155197              0.9203607              0.9352634
MSFT.Close              0.9520073              0.9549270              0.9543796
GOOG.Close              0.9791734              0.9631053              0.9652081

与这里的最终输出相比,行和列被转置。如果使用t (管道中的第二个函数)传输此矩阵,则得到所需的输出矩阵。最后一个函数as.xts简单地将矩阵转换为一种特殊类型的时间序列对象,即xts对象。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43173473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档