【问题标题】:How to replace values in an xts object based on conditions from other xts object如何根据其他 xts 对象的条件替换 xts 对象中的值
【发布时间】:2018-09-28 21:28:10
【问题描述】:

我有两个 xts 对象。

第一个“stocks_purchase_dates”包含 4 只股票的开盘日期和购买价格。

stocks_purchase_dates             

           stock1 stock2 stock3 stock4
2018-03-19     NA     NA     NA 165.78
2018-03-21     NA   36.1     NA     NA
2018-03-23     23     NA     NA     NA
2018-03-26     NA     NA  48.81     NA

第二个“stocks_prices_mar15_mar28”包含 2018 年 3 月 15 日至 3 月 28 日期间 4 只股票的价格。

stocks_prices_mar15_mar28                         

           stock1 stock2 stock3 stock4
2018-03-15  23.30  44.28  54.75 177.34
2018-03-16  23.06  45.12  55.10 176.72
2018-03-19  23.31  44.44  54.31 174.02
2018-03-20  23.75  44.82  54.06 173.96
2018-03-21  23.92  43.19  53.91 170.02
2018-03-22  23.47  41.27  51.68 167.61
2018-03-23  23.43  39.96  49.90 163.73
2018-03-26  24.16  38.27  51.68 171.50
2018-03-27  23.40  37.19  50.10 167.11
2018-03-28  23.27  36.99  50.94 165.26

在“stocks_prices_mar15_mar28”中,我想将每只股票在开盘日期之前的值(在“stocks_purchase_dates”中给出)替换为 0。

一种可能的解决方案是用列和日期替换:

stocks_prices_mar15_mar28[,"stock1"]["/2018-03-22", ] <- 0
stocks_prices_mar15_mar28[,"stock2"]["/2018-03-20", ] <- 0
stocks_prices_mar15_mar28[,"stock3"]["/2018-03-25", ] <- 0
stocks_prices_mar15_mar28[,"stock4"]["/2018-03-18", ] <- 0

输出是:

stocks_prices_mar15_mar28             

           stock1 stock2 stock3 stock4
2018-03-15   0.00   0.00   0.00   0.00
2018-03-16   0.00   0.00   0.00   0.00
2018-03-19   0.00   0.00   0.00 165.78
2018-03-20   0.00   0.00   0.00 173.96
2018-03-21   0.00  36.10   0.00 170.02
2018-03-22   0.00  41.27   0.00 167.61
2018-03-23  23.00  39.96   0.00 163.73
2018-03-26  24.16  38.27  48.81 171.50
2018-03-27  23.40  37.19  50.10 167.11
2018-03-28  23.27  36.99  50.94 165.26

这行得通,但如果我们有更多的库存和开盘日期,它会变得很辛苦和复杂。

有什么方法可以更有效地完成任务,例如使用 apply 或 for 循环或 purrr 包中的函数?

【问题讨论】:

    标签: r replace xts


    【解决方案1】:

    我使用for 循环来循环列名。使用!is.na(stocks_purchase_dates$stock1),您可以找到哪个stock1 记录不是NA。使用which 可以找到这条记录的位置。使用.index,您可以在 xts 对象中进行过滤。所以我们可以做的是检查stocks_prices_mar15_mar28 的索引是否低于我们使用which 和!is.na 查找的stocks_purchase_dates 记录索引,然后将这些记录设置为0。

    现在,这只适用于每只股票在 stock_purchase_dates 中只有 1 条购买记录的情况。

    for(i in names(stocks_purchase_dates)) {
      stocks_prices_mar15_mar28[, i][.index(stocks_prices_mar15_mar28[, i]) < index(stocks_purchase_dates[, i])[which(!is.na(stocks_purchase_dates[, i]))]] <- 0
    }
    
    stocks_prices_mar15_mar28
               stock1 stock2 stock3 stock4
    2018-03-15   0.00   0.00   0.00   0.00
    2018-03-16   0.00   0.00   0.00   0.00
    2018-03-19   0.00   0.00   0.00 174.02
    2018-03-20   0.00   0.00   0.00 173.96
    2018-03-21   0.00  43.19   0.00 170.02
    2018-03-22   0.00  41.27   0.00 167.61
    2018-03-23  23.43  39.96   0.00 163.73
    2018-03-26  24.16  38.27  51.68 171.50
    2018-03-27  23.40  37.19  50.10 167.11
    2018-03-28  23.27  36.99  50.94 165.26
    

    在代码中复制和替换值时,请注意所有括号和大括号。

    【讨论】:

    • 非常感谢@phiver。你的回答对我帮助很大。只是对您的解决方案进行了一个小更正:索引 [.index(stocks_prices_mar15_mar28[, i] 前面有一个点,必须删除它才能使代码正常工作。
    • 它应该与点一起使用,但没有它也可以。有关名称前带点的更多功能,请参阅?.index 或?indexClass。方便在 xts 中更改/选择时间组件。
    • 当我执行带有点的代码时,它以初始形式返回“stocks_prices_mar15_mar28”,没有 0。
    猜你喜欢
    • 2013-12-30
    • 2020-04-16
    • 2019-03-19
    • 2013-05-27
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    • 1970-01-01
    • 2015-03-04
    相关资源
    最近更新 更多