使用自定义函数(if语句系列)

时间:2013-01-07 13:10:36

标签: r apply lapply sapply

我想运行一个查看两个向量的函数,根据两个向量中值的符号返回不同的值。我编写了一个函数来比较两个值,但后来我想在两个向量上运行它。所以我使用了sapply,但是得到的结果与预期不同。

bear.correction<-  function(x,y){
                                if(x > 0 && y < 0){
                                  return(90)
                                }else if(x < 0 && y < 0){
                                  return(180)
                                }else  if(x < 0 && y > 0){
                                  return(270)
                                }else   return(0)
                              }

以下给出了预期的(和期望的)结果:

  bear.correction(1,-1)
  bear.correction(1,1)
  bear.correction(-1,1)
  bear.correction(-1,-1)

结果:90,0,270,180

然而,当我尝试进行相同的比较,但使用带有sapply的向量时,我得到了不同的结果:

  x <- c(1,1,-1,-1)
  y <- c(-1,1,1,-1)
  sapply(x,bear.correction,y)

结果:90,90,180,180。

我看不出有什么问题,所以请帮忙!

4 个答案:

答案 0 :(得分:11)

您应该使用mapply()代替sapply()

mapply(bear.correction,x,y)

为什么呢?您的sapply()bear.correction()应用于x的每个条目...但在每种情况下都将整个 y向量作为第二个参数,所以bear.correction()仅查看所有四种情况下y中的第一个条目。要“遍历”多个向量(或其他数据结构)中的多个条目,请使用mapply()

答案 1 :(得分:5)

你应该使用mapply而不是sapply

mapply(bear.correction,x,y)

[1]  90   0 270 180

答案 2 :(得分:4)

在你的函数中添加browser(),如下所示:

bear.correction<-  function(x,y){

  browser()
  if(x > 0 && y < 0){
    return(90)
  }else if(x < 0 && y < 0){
    return(180)
  }else  if(x < 0 && y > 0){
    return(270)
  }else   return(0)
}

您将看到与参数完全相同的内容:

Browse[1]> x
[1] 1
Browse[1]> y
[1] -1  1  1 -1

正如其他人在这里所说,你需要使用mapply来给出标量值,而不是原子向量。

但我认为在这里使用plyr非常简单(输出格式不错)

library(plyr)
dat <- data.frame(x=x,y=y)
ddply(dat,.(x,y),function(r) bear.correction(r$x,r$y))
   x  y  V1
1 -1 -1 180
2 -1  1 270
3  1 -1  90
4  1  1   0

答案 3 :(得分:3)

如果你想使用apply,你必须改变你的功能:

bear.correction<-  function(xy){
                                if(xy[1] > 0 && xy[2] < 0){
                                  return(90)
                                }else if(xy[1] < 0 && xy[2] < 0){
                                  return(180)
                                }else  if(xy[1] < 0 && xy[2] > 0){
                                  return(270)
                                }else   return(0)
                              }

此功能现在采用2个值xy的向量,并使用第一个像您的旧x,第二个像您的旧y

x <- c(1,1,-1,-1)
y <- c(-1,1,1,-1)

xyx<-cbind(x,y)


apply(xyx,1, bear.correction)