我有这个示例数据,我加载了一些代码
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"
但它无法正常工作。并建议如何解决它? 感谢
答案 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$AMAT
或symb[["AMAT"]]
,具体取决于您希望如何提取数据。后一种形式更灵活,因为您可以指定具有特定值的变量,或者您可以通过lapply
对列表中的所有data.sets执行操作。
答案 2 :(得分:0)
在第一种情况下,您传递的是名为AMD
的数据框;在第二个你只是传递一个字符值"AMD"
。
我猜测数据框AMD
已经加载到您的工作空间中,这就是FUNtest
在第一种情况下工作的原因。
如果你想让函数工作,可以尝试将你想要的数据帧传递给函数,或者告诉函数在哪里找到你想要的数据框。