我想运行一个查看两个向量的函数,根据两个向量中值的符号返回不同的值。我编写了一个函数来比较两个值,但后来我想在两个向量上运行它。所以我使用了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。
我看不出有什么问题,所以请帮忙!
答案 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)