7

我想运行一个查看两个向量的函数,根据两个向量中值的符号返回不同的值。我写了一个函数来比较两个值,但是我想在两个向量上运行它。所以我使用了 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

4 回答 4

11

您应该使用mapply()而不是sapply()

mapply(bear.correction,x,y)

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

于 2013-01-07T13:17:57.313 回答
5

您应该使用 mapply 而不是 sapply

mapply(bear.correction,x,y)

[1]  90   0 270 180
于 2013-01-07T13:17:15.193 回答
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
于 2013-01-07T13:18:23.037 回答
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)
于 2013-01-07T13:22:14.403 回答