R:使用向量参数进行映射

时间:2018-04-14 18:54:45

标签: r multiple-columns mapply

我有这种形式的功能:

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!

1 个答案:

答案 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)