在 R 中的多个 data.frame 个大小不等的对象中查找最近日期

Find most recent date in multiple data.frame objects of unequal sizes in R

我有多个 data.frame 个长度不等的对象。我想在所有这些中找到最近的日期并将数据存储在某个地方。

这是一个希望可重现的代码示例,用于说明我想要的内容(带有注释和来源)。这给出了 7 data.frame 个可变长度的对象:

library(quantmod)

# Load ticker data from 2020-01-01 till 2021-02-02
tickers <- c("NKLA", "MPNGF", "RMO", "JD", "COIN")
getSymbols.yahoo(tickers, auto.assign = TRUE, env = globalenv(), from = "2020-01-01", to = "2021-02-02")

# Load ticker data from 2020-01-01 till yesterday (if not weekend or holiday)
tickers2 <- c("IBM", "AAPL", "MRNA")
getSymbols.yahoo(tickers2, auto.assign = TRUE, env = globalenv(), from = "2020-01-01")

# Close all Internet connections as a precaution
# 
closeAllConnections()

# Find xts objects
xtsObjects <- names(which(unlist(eapply(.GlobalEnv, is.xts))))

# Convert xts to data.frame
# 
for (i in seq_along(xtsObjects)) {
  assign(xtsObjects[i], fortify.zoo(get(xtsObjects[i])))
}

# 1st column name from Index to Date
# 
for (i in seq_along(xtsObjects)) {
  tmp <- get(xtsObjects[i])
  colnames(tmp)[colnames(tmp) == "Index"] <- "Date"
  assign(xtsObjects[i], tmp)
}
remove(tmp)

单独检索日期非常简单:

max(AAPL$Date)
max(IBM$Date)
max(JD$Date)
max(MPNGF$Date)
max(MRNA$Date)
max(NKLA$Date)
max(RMO$Date)

但是当我尝试以下代码时 none 它们会呈现,或者更好的是,存储具有相应来源(即代码)的最近日期:

dataframeObjects <- names(which(unlist(eapply(.GlobalEnv, is.data.frame))))

# Tentative 1    
for (i in seq_along(dataframeObjects)) {
  mostRecentDates <- max(dataframeObjects[i]$Date)
}

# Tentative 2
for (i in 1:length(dataframeObjects)) {
  mostRecentDates <- max(dataframeObjects[i]["Date"])
}

在调用变量 mostRecentDates 时,两种尝试都给出 [1]NA

重要:在最终代码中不会有任何 tickerstickers2 变量。将有一定数量的 data.frame 对象将在本地加载,并且将搜索这些对象以获得最后可用日期。

我的问题:

提前致谢。


使用的系统:

我们可以从ls中的对象名intersectticker个对象中获取对象,使用mget获取[=中对象的值19=],用 lapply 遍历 list,提取 'Date' 列并得到 max

do.call(c, lapply(mget(intersect(c(tickers, tickers2), ls())), 
       function(x) max(x$Date)))

-输出

   NKLA        MPNGF          RMO           JD          IBM         AAPL         MRNA 
"2021-02-01" "2021-02-01" "2021-02-01" "2021-02-01" "2021-09-28" "2021-09-28" "2021-09-28" 

更新

如果 ls() 中的对象仅来自使用 dataframeObjects 创建的对象,则执行

do.call(c, lapply(mget(dataframeObjects), function(x) max(x$Date)))

在 OP 的代码中,dataframeObjects 只是对象的名称。我们需要在循环中 get 到 return 值

# // in case there are other data.frame objects as well, get the intersect
nm1 <- intersect(dataframeObjects, c(tickers, tickers2))
# // create a `list` to store the output
out <- vector('list', length(nm1))
names(out) <- nm1
for(i in seq_along(nm1)) {
   out[[i]] <- max(get(nm1[i])$Date)
}

-输出

> out
$RMO
[1] "2021-02-01"

$NKLA
[1] "2021-02-01"

$JD
[1] "2021-02-01"

$AAPL
[1] "2021-09-28"

$IBM
[1] "2021-09-28"

$MRNA
[1] "2021-09-28"

$MPNGF
[1] "2021-02-01"

我建议将 xts 对象存储在另一个 environment 而不是全局对象中,这样更容易处理它们。我们可以将该环境变成一个列表,然后我们可以使用 purrr::map()base::lapply().

迭代该列表

这是您的示例的样子。

library(quantmod)
library(tidyverse)
sym_env <- new.env()

tickers <- c("NKLA", "MPNGF", "RMO", "JD", "COIN")
getSymbols.yahoo(tickers, auto.assign = TRUE, env = sym_env, from = "2020-01-01", to = "2021-02-02")

tickers2 <- c("IBM", "AAPL", "MRNA")
getSymbols.yahoo(tickers2, auto.assign = TRUE, env = sym_env, from = "2020-01-01")

closeAllConnections()

as.list(sym_env) |> 
  map(fortify.zoo) |> 
  map(\(x) rename(x, Date=Index)) |> 
  map(\(x) max(x$Date))

Returns:

$RMO
[1] "2021-02-01"

$NKLA
[1] "2021-02-01"

$JD
[1] "2021-02-01"

$AAPL
[1] "2021-09-28"

$IBM
[1] "2021-09-28"

$MRNA
[1] "2021-09-28"

$MPNGF
[1] "2021-02-01"

一般来说,建议将应该使用相同功能处理的数据对象组织在 list 中,而不是将它们混合到全局环境中。因此,您应该选择一种获取数据的方法 returns a list.

您可以使用任何其他策略来获取 xts 对象列表,然后将其提供给 purrr::map() 命令链。

list_of_xts_objects |> 
  map(fortify.zoo) |> 
  map(\(x) rename(x, Date=Index)) |> 
  map(\(x) max(x$Date))