将变量加载到R中的函数中

时间:2014-07-24 14:40:49

标签: r function

我有这个示例数据,我加载了一些代码

libs <- c('quantmod')
lapply(libs, require, character.only = T)
tickers<-c('T','AMD','AA','AMAT','BAC')
getSymbols(tickers,from="2013-01-01")

然后我创建了像

这样的函数
FUNtest<-function (x,y){
  data<-x
  close<-data[,y]
  return(tail(close))
}

其作用类似于

FUNtest(AMD,4)

结果是AMD收盘价的尾声

           AMD.Close
2014-07-16      4.66
2014-07-17      4.57
2014-07-18      3.83
2014-07-21      3.78
2014-07-22      3.80
2014-07-23      3.76

但是,为了以后的使用,我需要能够以这种方式使用函数

FUNtest(tickers[2],4)

但它不起作用。如果我打电话

tickers[2]

显示

> tickers[2]
[1] "AMD"

但它无法正常工作。并建议如何解决它? 感谢

3 个答案:

答案 0 :(得分:1)

您可以尝试在函数中使用get

get("AMD")在评估框架中找到AMD(或不),并返回附加到其上的值。

> FUNtest<-function (x,y){
     data<-get(x)
     close<-data[,y]
     return(tail(close))
 }
> FUNtest(tickers[2], 4)
#            AMD.Close
# 2014-07-16      4.66
# 2014-07-17      4.57
# 2014-07-18      3.83
# 2014-07-21      3.78
# 2014-07-22      3.80
# 2014-07-23      3.76

此外,此处并不需要使用return。这个功能对你来说可能更好

> f <- function(x, y){ x <- get(x); tail(x[, y], 3) }
## on the entire tickers vector, get column 4 and bind them
> do.call(cbind, lapply(tickers, f, y = 4))
#            T.Close AMD.Close AA.Close AMAT.Close BAC.Close
# 2014-07-16   36.45      4.66    16.60      22.85     15.51
# 2014-07-17   36.03      4.57    16.33      22.77     15.20
# 2014-07-18   36.17      3.83    16.49      23.00     15.49

eval对于不带引号的参数

也非常有用
> f <- function(x){ eval(x) }
> head(f(AMD), 3)
#            AMD.Open AMD.High AMD.Low AMD.Close AMD.Volume AMD.Adjusted
# 2013-01-02     2.55     2.57    2.45      2.53   27214800         2.53
# 2013-01-03     2.52     2.59    2.46      2.49   24966900         2.49
# 2013-01-04     2.51     2.59    2.49      2.59   22054200         2.59

答案 1 :(得分:1)

之间存在很大差异
FUNtest(AMD,4)

FUNtest("AMD",4)

使用前者,您传递的name指向xts个对象。在后者中,您只是传递一个字符串。此字符串绝不会直接连接到同名对象。

如果你想要一个在你传递一个角色或xts对象时有效的功能,你可以这样做

FUNtest<-function (x,y){
  if(is(x, "xts")) {
      data <- x
  } else if (is(x, "character")) {
      data <- get(x)
  } else {
    stop(paste("invalid x class:", class(x)))
  }
  close <- data[,y]
  return(tail(close))
}

然后两者

FUNtest(AMD, 4)
FUNtest(tickers[2], 4)

会奏效。

但更好的是不要使用quantmod的行为,它会在您的全局环境中添加变量。这是被淘汰的默认值,因为它会鼓励不良行为。最好将它们全部存储在像

这样的列表中
symb<-lapply(setNames(tickers, tickers), function(x) 
    getSymbols(x,from="2013-01-01",  auto.assign=F))

然后,您可以拥有symb$AMATsymb[["AMAT"]],具体取决于您希望如何提取数据。后一种形式更灵活,因为您可以指定具有特定值的变量,或者您可以通过lapply对列表中的所有data.sets执行操作。

答案 2 :(得分:0)

在第一种情况下,您传递的是名为AMD的数据框;在第二个你只是传递一个字符值"AMD"

我猜测数据框AMD已经加载到您的工作空间中,这就是FUNtest在第一种情况下工作的原因。

如果你想让函数工作,可以尝试将你想要的数据帧传递给函数,或者告诉函数在哪里找到你想要的数据框。