我有这种形式的功能:
foo<-function(x,y){
if(length(y)==1){
return(x*y)
}
else{
return(x-y[1]*y[2])
}
}
并且对于 y 参数,我传递数字或数字向量:
> #test function:
> foo(1,2)
[1] 2
> foo(1,c(1,2))
[1] -1
现在我希望使用mapply来处理这个函数,但是当我希望为 y 参数传递一个向量时,我会遇到问题:
df<-data.frame(
"a"<-floor(runif(6, 1,10)),
"b"<-floor(runif(6, 18,80)),
"c"<-floor(runif(6, 1,80)),
"d"<-floor(runif(6, 100,800)),
"e"<-floor(runif(6, 1000,4000)),
"f"<-floor(runif(6, 1,10)),
"g"<-floor(runif(6, 5,80))
)
names(df)=c("a","b","c","d","e","f","g")
以下工作正常:
> mapply(FUN=foo,df["a"],df["b"])
,但是当我尝试执行以下操作时遇到了麻烦:
> mapply(FUN=foo,df["a"],cbind(df["b"],df["c"]))
我非常感谢有关如何更好地使用具有非常长度的参数的提示,或者如何将参数传递给mapply!
答案 0 :(得分:1)
这里有很多可能的修复方法。从根本上说,您需要将第二个输入转换为mapply
到一个列表中,每个列表中包含两个元素。实现这一目标的一种方法是执行以下操作:
tmp <- as.data.frame(t(df[c('b', 'c')]))
result <- mapply(FUN=foo,df["a"], tmp)
因为数据框是一个列表。这将在df["a"]
和tmp
的所有组合上运行该功能。你想要的元素将沿着对角线(df['a']
的第一个元素与tmp的第一个元素,所以最终的答案是
diag(result)
顺便说一句,如果你在data.frame
这样的函数中,请使用=
代替<-
。你也不需要字母周围的引号(它们被忽略)。所以你打电话给data.frame
应该是
df<-data.frame(
a = floor(runif(6, 1,10)),
b = floor(runif(6, 18,80)),
c = floor(runif(6, 1,80)),
d = floor(runif(6, 100,800)),
e = floor(runif(6, 1000,4000)),
f = floor(runif(6, 1,10)),
g = floor(runif(6, 5,80))
)
这使您可以避免在定义数据框后对其进行命名。
无对角线通话更新
f1 <- function(x) {
if(length(x) ==2 ) x[1] * x[2]
else x[1] - x[2]*x[3]
}
apply(df[,c("a","b", "c")], 1, f1)