R:if else 语句将列作为整个向量处理

R: if else statement is handling column as whole vector

我有一个数据集,我想用 tq_get 计算 6 个月 return 的股票(参见下面的示例)

名为 top

的数据集
ticker 6month
AKO.A
BIG
BGFV

函数

library(tidyverse)
library(dplyr)
library(tidyquant)
library(riingo)

calculate <- function (x) {
  (tq_get(x, get = "tiingo", from = yesterday, to = yesterday)$adjusted/tq_get(x, get = "tiingo", from = before, to = before)$adjusted)-1
}

top[2] <- lapply(top[1], function(x) calculate(x))

不幸的是,对于某些代码,不存在任何值,这会导致在仅使用 lapplymutate 时出现错误消息,因为生成的向量比现有数据集更小(行数更少)。使用 try_catch 解析无效。

我现在想通过检查软件包 riingo 提供的 is_supported_ticker() 来解决代码是否可用

calculate <- function (x) {
  if (is_supported_ticker(x, type = "tiingo") == TRUE) {
  (tq_get(x, get = "tiingo", from = yesterday, to = yesterday)$adjusted/tq_get(x, get = "tiingo", from = before, to = before)$adjusted)-1
  }
  else {
    NA
  }
}

top[2] <- lapply(top[1], function(x) calculate(x))

但现在我收到错误消息 x ticker must be length 1, but is actually length 3

我假设这是基于这样一个事实,即我的数据集的整个第一列都用作 is_supported_ticker() 的输入,而不是逐行输入。我该如何解决这个问题?

看了一下文档,好像tq_get支持多个符号,只有if_supported_ticker一次一个。因此,您可能应该检查所有代码以查看它们是否受支持,然后在所有受支持的代码上使用 tq_get 一次。像这样的东西(未经测试,因为我没有这些包中的任何一个):

calculate <- function (x) {
  supported = sapply(x, is_supported_ticker, type = "tiingo")
  result = rep(NA, length(x))
  result[supported] = 
    (
      tq_get(x[supported], get = "tiingo", from = yesterday, to = yesterday)$adjusted / 
      tq_get(x[supported], get = "tiingo", from = before, to = before)$adjusted
    ) - 1
  return(result)
}

令我担心的是 beforeyesterday 不是函数参数 - 它们只是假定存在于全局环境中。我建议将它们作为参数传递给 calculate(),如下所示:

calculate <- function (x, before, yesterday) {
  supported = sapply(x, is_supported_ticker, type = "tiingo")
  result = rep(NA, length(x))
  result[supported] = 
    (
      tq_get(x[supported], get = "tiingo", from = yesterday, to = yesterday)$adjusted / 
      tq_get(x[supported], get = "tiingo", from = before, to = before)$adjusted
    ) - 1
  return(result)
}

# then calling it
calculate(top$ticker, before = <...>, yesterday = <...>)

通过这种方式,您可以即时传递 beforeyesterday 的值。如果它们是您全局环境中的对象,您可以简单地使用 calculate(top$ticker, before, yesterday),但它使您可以自由地改变这些参数,而无需在您的全局环境中重新定义这些名称。