简体   繁体   English

使用ifelse的函数不返回R中的向量

[英]Function using ifelse not returning a vector in R

I wrote a somewhat grotesque function, which should simply return a vector with two values. 我写了一个有点怪诞的函数,它应该只返回一个带有两个值的向量。

For example, if you put in 33 , you should get back c(30, 40) . 例如,如果你输入33 ,你应该回到c(30, 40) It couldn't get much simpler than this. 它不会比这简单得多。

return_a_range <- function(number){
    ans <-  ifelse(  (30  <= number & number <= 40), c(30, 40),
                     (ifelse( (40  < number  & number  <= 50), c(40, 50),
                              (ifelse( (50  < number  & number  <= 60), c(50, 60),
                                       (ifelse( (60  < number  & number  <= 70), c(60, 70),
                                                (ifelse( (70  < number  & number  <= 80), c(70, 80),
                                                         (ifelse( (80  < number  & number  <= 100), c(80, 100),                      
                                                                           ans <- c("NA"))))))))))))
    return(ans)}

return_a_range(33)

Why is this returning only 30 ? 为什么这只返回30 How am I not getting back c(30, 40) ? 我怎么不回来c(30, 40) Why did R decide to only return the value in the first position of the vector? 为什么R决定只返回向量的第一个位置的值?

EDIT 编辑
Although most of the responses are concerned with (justifiably!) spanking me for writing a lousy ifelse statement, I think the real question was recognized and answered best by @MrFick in the comments directly below. 虽然大多数回答都是(有理由!) ifelse我写一篇糟糕的ifelse陈述,但我认为真正的问题在下面的评论中得到了@MrFick的认可和回答。

You could just use: 你可以使用:

> c(floor(33 / 10), ceiling(33 / 10))*10
[1] 30 40

Or as a function - thanks to @Khashaa for a nice modification (in the comments): 或者作为一个函数 - 感谢@Khashaa做了一个很好的修改(在评论中):

f <- function(x) if(abs(x) >= 100) NA else c(floor(x / 10), floor(x/10) + 1)*10
f(44)
#[1] 40 50

f(40)
#[1] 40 50

This kind of functions will be a lot more efficient than multiple nested ifelse s. 这种函数比多个嵌套ifelse更有效。


I overlooked initially that you want to return 30 - 40 for a input value of 40 (I thought you wanted 40 - 50 which is what the above function does). 我最初忽略了你想要返回30 - 40输入值为40(我认为你想要40 - 50这就是上面的功能)。

So this is a slightly more elaborate function which should implement that behavior: 所以这是一个稍微复杂一点的函数,它应该实现这种行为:

ff <- function(x) {
  if (abs(x) >= 100L) {
    NA 
  } else {
    y <- floor(x / 10L) * 10L
    if (x %% 10L == 0L) {
      c(y - 10L, y) 
    } else {
      c(y, y + 10L)
    }
  }
}

And in action: 并在行动:

ff(40)
#[1] 30 40
ff(45)
#[1] 40 50

Or if you had a vector of numbers you could lapply/sapply over it: 或者,如果你有一个数字向量,你可以为它提供lapply / sapply:

( x <- sample(-100:100, 3, F) )
#[1]  73  89 -97

lapply(x, ff)
#[[1]]
#[1] 70 80
#
#[[2]]
#[1] 80 90
#
#[[3]]
#[1] -100  -90

Or 要么

sapply(x, ff)
#     [,1] [,2] [,3]
#[1,]   70   80 -100
#[2,]   80   90  -90

Here's another variation using %/% which will work for f2(40) case too (but my fail somewhere else?) 这是另一个使用%/%变体,它也适用于f2(40)情况(但我在其他地方失败了吗?)

f2 <- function(x) if(abs(x) >= 100) NA else c(x %/% 10, (x + 10) %/% 10) * 10
f2(40)
## [1] 40 50

If you really want to use your function the way you use it and not go with docendo's answer (where for this problem I don't see why) you can do the following (in case you need to do something similar in the future): 如果你真的想以你使用它的方式使用你的功能而不是docendo的答案(这个问题我不明白为什么)你可以做以下事情(如果你将来需要做类似的事情):

return_a_range <- function(number){
  ans <-  ifelse(  (30  <= number & number <= 40), a<-c(30, 40),
                   (ifelse( (40  < number  & number  <= 50), a<-c(40, 50),
                            (ifelse( (50  < number  & number  <= 60), a<-c(50, 60),
                                     (ifelse( (60  < number  & number  <= 70), a<-c(60, 70),
                                              (ifelse( (70  < number  & number  <= 80), a<-c(70, 80),
                                                       (ifelse( (80  < number  & number  <= 100), a<-c(80, 100),                      
                                                                a <- c("NA"))))))))))))
  return(a)}

> return_a_range(33)
[1] 30 40

> return_a_range(62)
[1] 60 70

The only thing I did was to save the vector in a variable a on each ifelse . 我唯一做的就是将矢量保存在每个ifelse的变量a

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM