【问题标题】:R calculate a new column for multiple dataframes with a map-function or a loopR使用映射函数或循环计算多个数据帧的新列
【发布时间】:2019-01-28 14:29:24
【问题描述】:

我在使用 map 函数或 for 循环为多个数据框创建新列时遇到问题。我有 25 个包含加密货币时间序列数据的数据框:

ls(pattern="USD")
[1] "ADA.USD"   "BCH.USD"   "BNB.USD"   "BTC.USD"   "BTG.USD"   "DASH.USD"      "DOGE.USD"  "EOS.USD"   "ETC.USD"   "ETH.USD"   "IOT.USD"
[12] "LINK.USD"  "LTC.USD"   "NEO.USD"   "OMG.USD"   "QTUM.USD"  "TRX.USD"   "USDT.USD"  "WAVES.USD" "XEM.USD"   "XLM.USD"   "XMR.USD"
[23] "XRP.USD"   "ZEC.USD"   "ZRX.USD" 

每个对象都是一个数据框,代表以美元表示的加密货币。每个数据框都有 2 列:日期和收盘价(收盘价)。例如:数据框“BTC.USD”代表美元中的比特币:

head(BTC.USD)
# A tibble: 6 x 2
Date       Close
1 2015-12-31  430.
2 2016-01-01  434.
3 2016-01-02  434.
4 2016-01-03  431.
5 2016-01-04  433.

现在我想添加第三列,代表每日收益。

require(quantmod)
BTC.USD <- BTC.USD%>%mutate(Return= Delt(Close)*100)

对于单个对象(在本例中为比特币 [BTC.USD]),此代码可以正常工作:

> head(BTC.USD)
# A tibble: 6 x 3
  Date       Close Return[,"Delt.1.arithmetic"]
  <date>     <dbl>                        <dbl>
1 2015-12-31  430.                      NA     
2 2016-01-01  434.                       0.940 
3 2016-01-02  434.                      -0.0622
4 2016-01-03  431.                      -0.696 
5 2016-01-04  433.                       0.608 
6 2016-01-05  431.                      -0.489 

现在我想使用映射函数或 for 循环计算所有 25 个数据帧(或加密货币)的回报,但我的代码不起作用:

temp = ls(pattern=".USD")
map(.x= temp,.f = mutate(Return= Delt(Close)*100))

is.data.frame(.data) 中的错误 ||是.list(.data) || is.environment(.data) : 缺少参数“.data”,没有默认值

for (i in seq_along(temp)) {mutate(Return= Delt(Close)*100)}

is.data.frame(.data) 中的错误 ||是.list(.data) || is.environment(.data) : 缺少参数“.data”,没有默认值

有人可以帮我吗?

【问题讨论】:

  • lapply(temp, function(x) mutate(x, Return = Delt(Close)*100)) 也许?
  • 变异错误(x, Return = Delt(Close) * 100) : is.data.frame(.data) ||是.list(.data) || is.environment(.data) 不是 TRUE
  • temp 只是一个字符向量,它不包含任何实际数据。您需要将数据放入列表中,然后@LAP 的评论才会起作用。
  • 我认为没有理由不将所有数据放在一个列表中。

标签: r for-loop map-function


【解决方案1】:

首先,我们需要以列表的形式实际获取数据(每个data.frame 都会在列表中获得自己的条目)。然后,我们可以使用任何我们喜欢的列表迭代函数来获得所需的结果。

temp_data <- lapply(ls(pattern = "USD"), get) # get data into a list
temp_data2 <- lapply(temp_data, function(x) mutate(x, Return = Delt(Close)*100))

正如@akrun 所说,有一种更紧凑的方法可以做到这一点:

lapply(mget(ls(pattern = "USD")), transform, Return = Delt(Close) * 100)

如果你想坚持使用tidyverse 动词,那就是:

lapply(mget(ls(pattern = "USD")), function(x) x %>% mutate(Return = Delt(Close) * 100))

我可以使用您的示例数据使代码正常工作:

sdat1 <-structure(list(
      Date = c("2015-12-31","2016-01-01",
               "2016-01-02","2016-01-03","2016-01-04"),
      Close = c(430, 434, 434, 431, 433)),
    class = "data.frame",
    row.names = c("1", "2", "3", "4", "5"))

sdat4 <- sdat3 <- sdat2 <- sdat1

lapply(mget(ls(pattern = 'sdat')),
       FUN = function(x) x %>% mutate(Return = Delt(Close)))

【讨论】:

  • 这也不起作用:Lag.default(x1, K.) 中的错误:x 必须是时间序列或数字向量
  • 感谢@akrun,我将其添加到我的答案中。如果您希望将其发布为您自己的,我很乐意编辑我的答案并将其删除。
  • 不,这只是对您的解决方案的简单修改。所以请不要删除它
  • 没有。相同的答案:Error in Lag.default(x1, K.) : x must be a time series or numeric vector
  • 我从您的问题中提取了样本数据,将其副本放入列表中,然后运行代码。它对我有用。
猜你喜欢
  • 2022-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多