【问题标题】:sapply with custom function (series of if statements)sapply 使用自定义函数(一系列 if 语句)
【发布时间】:2012-12-21 05:25:57
【问题描述】:

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

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

【问题讨论】:

  • 对不起@agstudy,我认为可以接受多个答案,但显然不是。我认为 Stephan Kolossa 的答案是最好的,尽管其他人也都有效,因此我的积极 cmets。
  • 没问题。希望对您有所帮助。

标签: r apply lapply sapply


【解决方案1】:

像这样在你的函数中添加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

【讨论】:

  • 谢谢,有调试建议很有用。 Pylr 替代品也不错。 pylr我用的不多,但它是一个很好的包。
【解决方案2】:

如果你想使用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)

【讨论】:

  • 谢谢。这也是一个不错的解决方案。
【解决方案3】:

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

mapply(bear.correction,x,y)

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

【讨论】:

  • 谢谢斯蒂芬。很好的答案和清晰的解释。我不知道 mapply()
【解决方案4】:

你应该使用 mapply 而不是 sapply

mapply(bear.correction,x,y)

[1]  90   0 270 180

【讨论】:

  • 谢谢,简洁明了。斯蒂芬也给出了很好的解释。
  • 有关 *apply 函数的未来参考,请查看question
  • 谢谢。这是一个非常有用的资源。我会把它加入书签。
猜你喜欢
  • 1970-01-01
  • 2022-06-10
  • 2019-06-06
  • 1970-01-01
  • 2011-10-14
  • 2014-10-14
  • 1970-01-01
  • 2021-09-26
  • 1970-01-01
相关资源
最近更新 更多