【问题标题】:R: Remove repeated values and keep the first one in a binary vectorR:删除重复值并将第一个值保留在二进制向量中
【发布时间】:2016-03-20 05:14:33
【问题描述】:

我想删除重复的,但将第一个保留在二进制向量中:

x = c(0,0,1,1,0,1,0,1,1,1,0,1) # the input 
y = c(0,0,1,0,1,0,1,0,1)     # the desired output

即分别删除第一组和第三组1中的一个1和两个1,并保留该组中的第一个。

我正在尝试将rlecumsum 一起使用,但尚未弄清楚。任何建议将不胜感激。

【问题讨论】:

  • 这是另一个x[ave(x, cumsum(x == 0), FUN = cumsum) <= 1]

标签: r indexing duplicates


【解决方案1】:

我们可以使用diff:

x[c(1, diff(x)) == 1 | x == 0]

【讨论】:

  • 如果想要对数据框进行子集化,如果向量是列之一,那么保留索引是很棒的。非常感谢!
【解决方案2】:
x = c(0,0,1,1,0,1,0,1,1,1,0,1)
x[!(x == 1 & #remove each value that is a 1
    c(x[-1] == 1, FALSE) #followed by a 1 (never the case for the last value)
  )]
#[1] 0 0 1 0 1 0 1 0 1

【讨论】:

  • 这显然比我的回答更简洁。你能解释一下这是如何工作的吗?
  • @BrantMullinix 我添加了 cmets。
  • 为什么会有向量 c(x[-1]==1,FALSE)?与只做 x[!(x == 1 & x[-1] == 1)] 有什么区别?
  • 对于其他想知道相同问题的人,我自己找到了答案。 x[-1] 返回一个没有第一个元素的向量,所以当你 & this 与第一部分时,向量长度不同。虽然 R 可以自己处理这个问题,但它有影响,不推荐。为了解决这个问题,@Roland 在向量的末尾添加了一个 FALSE,因为在此比较中最后一个值将是 false。这使得两个向量长度相等,避免了“较长的对象长度不是较短的对象长度的倍数”的警告。
【解决方案3】:

根据向量大小,您可以循环遍历它并使用条件将值附加到结果中。这是使用给定输入的简单解决方案。

x <- c(0,0,1,1,0,1,0,1,1,1,0,1)
prev <- 0
y <- c()
for(i in x){
  if (i == 1){
    if (prev != 1){
      y <- append(y,i)
    }
  }else{
    y <- append(y,i)
  }
  prev <- i
}

【讨论】:

  • 永远不要在循环中增长对象。请阅读The R Inferno
  • 感谢您的建议。 @罗兰
【解决方案4】:
x = c(0,0,1,1,0,1,0,1,1,1,0,1)
x1 <- rle(x)
x1$lengths[x1$values==1] <- 1
inverse.rle(x1)

【讨论】:

  • 这是我要发布的版本。
  • @David Arenburg 更快
【解决方案5】:

使用rle/inverse.rle

res <- rle(x)
res$lengths[res$values == 1] <- 1
inverse.rle(res)
## [1] 0 0 1 0 1 0 1 0 1

【讨论】:

  • inverse.rle(within(unclass(rle(x)),lengths[values==1]&lt;-1)) 使其成为单线。
  • @nicola 是的,我想把它做成一个班轮,但试图做with(rle(x), lengths[values == 1] &lt;- 1),由于某种原因它不起作用。使用 withinunclass 似乎很难阅读。
  • 不知道还有逆向,太好了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 2020-04-29
  • 2016-10-28
  • 1970-01-01
  • 2013-07-10
  • 1970-01-01
相关资源
最近更新 更多