为什么R中的xts对象除以常数会导致矩阵对象(丢失日期列)?

为什么R中的xts对象除以常数会导致矩阵对象(丢失日期列)?,r,type-conversion,xts,R,Type Conversion,Xts,感谢您在以下方面提供的帮助: 为什么用常数除以R中的xts对象会得到矩阵对象(日期/索引列丢失)? 我希望得到的对象是一个xts对象,就像输入xts一样,只有列值除以常量。为什么会发生这种情况以及如何避免 我观察到的问题的例子 代码摘录: TradeProfit <- as.xts(ifelse(is.na(lag(GLD$Signal, 1)) == 0 & GLD$Signal != lag(GLD$Signal, 1), GLD$TotTradCapital, NA )) T

感谢您在以下方面提供的帮助:

为什么用常数除以R中的xts对象会得到矩阵对象(日期/索引列丢失)? 我希望得到的对象是一个xts对象,就像输入xts一样,只有列值除以常量。为什么会发生这种情况以及如何避免

我观察到的问题的例子

代码摘录:

TradeProfit <- as.xts(ifelse(is.na(lag(GLD$Signal, 1)) == 0 & GLD$Signal != lag(GLD$Signal, 1), GLD$TotTradCapital, NA ))
TradeProfit <- na.omit(TradeProfit)

TradeProfitPerc <- ifelse(is.na(lag(TradeProfit,1)) == 0, TradeProfit / 100, NA)
TradeProfitPerc <- na.omit(TradeProfitPerc)

> class(TradeProfit)
[1] "xts" "zoo"

> head(TradeProfit)
              Signal
2012-08-15  0.000000
2012-11-02  6.970001
2012-11-06  6.970001
2013-08-09 46.410003
2013-08-14 46.410003
2013-09-27 46.380004

head(TradeProfitPerc)
        Signal
[1,] 0.06970001
[2,] 0.06970001
[3,] 0.46410003
[4,] 0.46410003
[5,] 0.46380004
[6,] 0.46380004

> class(TradeProfitPerc)
[1] "matrix"
> 
贸易利润
问题是TradeProfitPerc丢失了我想要保留的日期列/索引。另外,由于TradeProfit是xts对象,为什么分割会导致将xts转换为矩阵对象的奇怪行为?如何保留xts属性?
谢谢

如果我是你,我只需向现有对象添加一列,这将保留
xts

GLD <- xts(matrix(1:10,ncol=2),Sys.Date()+0:4)
colnames(GLD) <- c("Signal","TotTradCapital")
TradeProfit <- as.xts(ifelse(is.na(lag(GLD$Signal, 1)) == 0 & GLD$Signal != lag(GLD$Signal, 1), GLD$TotTradCapital, NA ))
TradeProfit <- na.omit(TradeProfit)

TradeProfit$TradeProfitPerc <- ifelse(!is.na(lag(TradeProfit,1)), TradeProfit / 100, NA)

           Signal TradeProfitPerc
2017-06-06      7              NA
2017-06-07      8            0.08
2017-06-08      9            0.09
2017-06-09     10            0.10

GLD这里有一个最小的、可重复的示例:

library(quantmod)
getSymbols("GLD")
GLD$GLD.SMA <- SMA(Cl(GLD), 50)
GLD$Signal <- Cl(GLD) > GLD$GLD.SMA

TradeProfit <- as.xts(ifelse(!is.na(lag(GLD$Signal, 1)) &
                             GLD$Signal != lag(GLD$Signal, 1), 100, NA))
TradeProfit <- na.omit(TradeProfit)

TradeProfitPerc <- ifelse(!is.na(lag(TradeProfit,1)), TradeProfit / 100, NA)
TradeProfitPerc <- na.omit(TradeProfitPerc)
您可以通过避免
ifelse
和直接子集设置来避免这种情况:

GLD$TotTradCapital <- 500
# rows where Signal is NA will be FALSE and therefore not included in TradeProfit
TradeProfit <- GLD[GLD$Signal != lag(GLD$Signal, 1), "TotTradCapital"]
TradeProfitPerc <- TradeProfit / 100

GLD$TotTradCapital感谢@PLapointe花时间回答。是的,你的解决方案有效。然而,我特别试图理解为什么我的代码不起作用,以便更好地理解什么代码对xts起作用或不起作用,并避免重复类似的错误。所以我更喜欢下面的J Ulrich答案来解释,即.na返回一个逻辑矩阵,因此我在上面的代码中观察到类型的变化。谢谢@菲利波内里一切都好。Joshua是
xts
软件包的作者。他最清楚。感谢Joshua Ulrich提供的详细答案,该答案提供了解决方案,并解释了为什么我的代码不起作用。请重新阅读您的答案,并解释为什么在变量TradeProfit的情况下,is.na()调用不会导致索引/日期列被删除?谢谢。现在很清楚了。我真的没有想到,也没有意识到,在将函数应用于xts对象时,类型可能会发生变化。@Filipboneri:这是
ifelse()
的一个怪癖,不是xts特有的。
GLD$TotTradCapital <- 500
# rows where Signal is NA will be FALSE and therefore not included in TradeProfit
TradeProfit <- GLD[GLD$Signal != lag(GLD$Signal, 1), "TotTradCapital"]
TradeProfitPerc <- TradeProfit / 100