理解一行R代码

时间:2017-04-02 00:17:25

标签: r

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

##            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(显然是一个“管道”操作符)并运行这行代码时:

stock_return <- apply(stocks, 1, function(x) {x / stocks[1,]}) %>% t %>% as.xts

你明白了:

           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.00投资如何随时间变化。

所以代码的这一部分是函数:

{x / stocks[1,]}) %>% t %>% 

它与“管道操作员”有关,操作从左到右而不是从里到外工作。有人可以帮助我理解这个函数的语法以及它如何实现它应该达到的目的吗?我可以使用它,但我宁愿没有它是一个黑盒子。谢谢!

1 个答案:

答案 0 :(得分:0)

首先要注意的是,此代码仅在输入为矩阵时才有效。 为了使其可重复读取数据如下:

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函数。

apply(df, 1, function(x) {x / df[1,]})

正如你所说的,它适用于矩阵的行,意思是
它占用了martix的每一行并将它们分别传递给提供的函数(实际上有一个for循环在后台工作)。一个函数的简单案例是mean

apply(stock, 1, mean)

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

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

x表示原始矩阵的一行,stock[1, ]是原始矩阵的第一行。因此,矩阵的每一行都是由矩阵的第一行一个接一个地划分,结果作为列添加到一个看起来像这样的新矩阵

                       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对象。