通过索引

时间:2019-02-16 13:53:05

标签: r if-statement indexing

我无法解决有关ifelse的问题:

说我有两个向量:

x <- c(0, 1:4, 1:4)
y <- letters[1:3]

当我这样做

ifelse(x==2, y[x], x)

我明白了

  

“ 0”“ 1”“ c”“ 3”“ 4”“ 1”“ c”“ 3”“ 4”

但是,它应该在向量"b"的位置2返回yifelse为什么要这么做?

5 个答案:

答案 0 :(得分:1)

您在第一个元素中使用0作为索引,这就是为什么对齐混乱的原因。

var uniqueTimes = Set<String>();
var newArr : [(startTime: String, switchInGroup: Bool)] = [];

//Add only the objects with unique startTime (first occurrence in original array)
for (st, sig) in sessionToDisplay{
  if(uniqueTimes.insert(st).inserted){
    newArr.append((st, sig));
  }
}

//Sort as you need
newArr.sort(by: { $0.startTime.compare(($1.startTime)) == .orderedAscending });

所以

y[x]

[1] "a" "b" "c" NA  "a" "b" "c" NA

因此y [x]的长度与x的长度不同。

你想要的是

> y[0]
character(0)
> y[1]
[1] "a"
> y[2]
[1] "b"
> y[3]
[1] "c"

但仅当第一个元素始终为0时。

旧答案 因为

> ifelse(x==2, y[x+1], x)
[1] "0" "1" "c" "3" "4" "1" "c" "3" "4"

返回

x <- c(0, 1:4, 1:4)

所以[1] 0 1 2 3 4 1 2 3 4 返回

x==2

所以1] FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE

y = letters[1:3]

您将获得第三和第七个字母。

ifelse的文档说,如果一个向量太短,它将被回收,这是您期望的 ifelse(x==2, y[x], x)

但是当我尝试

c("a","b","c","a","b","c","a")

我明白了

ifelse(x==3, y[x], x)

哪个告诉我回收工作没有达到我的预期。
这就是您得到结果的名义原因。之所以这样工作,是我现在不知道的原因,但是如果我弄清楚了,我会添加这个答案。我怀疑这与转换为字符串有关。

只要看着[1] "0" "1" "2" NA "4" "1" "2" NA "4" 我就知道

y[x]

顺便说一句,即使x为9,长度也只有8。

因此,这根本与ifelse()完全无关,这实际上与回收的另一个问题有关。

答案 1 :(得分:1)

为解释这种奇怪的行为,ifelse的源代码很有帮助(请参见下文)。

调用ifelse时,将评估作为参数testyesno传递的表达式,结果为:

Browse[2]> test
[1] FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE
Browse[2]> yes
[1] "a" "b" "c" NA  "a" "b" "c" NA 
Browse[2]> no
[1] 0 1 2 3 4 1 2 3 4

观察到y[x]使用x的值从y中选取值 并且值0为空(=忽略),大于3的值为NA, 这就是“ yes”参数变为

的原因
  

[1]“ a”“ b”“ c” NA“ a”“ b”“ c” NA

代码行

ans[test & ok] <- rep(yes, length.out = length(ans))[test & ok]
然后在最后应用

并使用TRUE逻辑向量有效地更新所有test元素:

yes[test]

结果为:

  

[1]“ c”“ c”

存储在结果索引3和7

ans[test & ok]

因此,问题是使用y[x]作为ifelse的第二个参数+非直觉的ifelse行为,使用逻辑索引从中选择“ TRUE”结果y[x] ...

经验教训:避免使用复杂的ifelse逻辑,它有很多副作用(例如,您可能会丢失正确的数据类型或属性)。

# ifelse function
function (test, yes, no) 
{
  if (is.atomic(test)) {
    if (typeof(test) != "logical") 
      storage.mode(test) <- "logical"
    if (length(test) == 1 && is.null(attributes(test))) {
      if (is.na(test)) 
        return(NA)
      else if (test) {
        if (length(yes) == 1) {
          yat <- attributes(yes)
          if (is.null(yat) || (is.function(yes) && identical(names(yat), 
                                                             "srcref"))) 
            return(yes)
        }
      }
      else if (length(no) == 1) {
        nat <- attributes(no)
        if (is.null(nat) || (is.function(no) && identical(names(nat), 
                                                          "srcref"))) 
          return(no)
      }
    }
  }
  else test <- if (isS4(test)) 
    methods::as(test, "logical")
  else as.logical(test)
  ans <- test
  ok <- !(nas <- is.na(test))
  if (any(test[ok])) 
    ans[test & ok] <- rep(yes, length.out = length(ans))[test & 
                                                           ok]
  if (any(!test[ok])) 
    ans[!test & ok] <- rep(no, length.out = length(ans))[!test & 
                                                           ok]
  ans[nas] <- NA
  ans
}

答案 2 :(得分:0)

来自注释:它返回c,因为:which(x==2)返回3和7。我不知道为什么它不回收7而仅选择3。因为y小于长度7

尝试:

ind<-which(x==2)
ind1<-ind[1]-1
ifelse(x==2,y[ind1],x)
[1] "0" "1" "b" "3" "4" "1" "b" "3" "4"

这是尝试做一个函数:

dynamic_index<-function(ind,x,y){
  x<-x
  y<-y
  ind1<-which(x==ind)
 ind2<-ind1[1]-1
  ifelse(x==ind,y[ind2],x)
}
dynamic_index(2,x,y)

答案 3 :(得分:0)

因为==函数返回逻辑向量,所以结果按原样出现:

x <- c(0, 1:4, 1:4)
y <- letters[1:3]

ifelse(x==2, y[x], x)

#look at x==2
x==2
[1] FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE

这是一个逻辑向量,在第三个位置(而非第二个位置)具有true,因此它是选定的y的第三个值。这也说明了为什么引用which的行为的答案不正确。

答案 4 :(得分:-1)

x <-c(0,1:4,1:4) y <-字母[1:3]

ifelse(x == 2,y [x],x)

否则,它将检查x中的每个位置。如果为true,则将打印y [x]位置,这意味着将检查x中的位置,并打印Y中的值的位置。它将检查所有X

中的值