【问题标题】:how to get single elements in a vector with repeated observations如何通过重复观察获得向量中的单个元素
【发布时间】:2022-06-10 18:18:09
【问题描述】:

我试图从 R 中的向量中获得单个非结果重复的观察,让我们举个例子: v <- c(1,1,1,2,2,2,1,1,1,2,1,1,2,2,2,2,2,1,1,1) 我需要的基本上是一个提供这个输出的函数 c(1,2,1,2,1,2,1) 我想到了一个 for 循环来做这件事,应该是这样的:

uniq_v <- v[1]
for(i in c(1:length(v)-1)[c(1:length(v)-1) >0]){
     if (v[i]!=v[i+1]){
    uniq_v <- c(uniq_v, v[i+1])
}
 }

我很确定有更好、更简单的方法,但我想不通。 谢谢, 朱塞佩

【问题讨论】:

标签: r string vector


【解决方案1】:

这个怎么样(使用 dplyr):

v[v!=lead(v)] %>% head(-1)

编辑: 我意识到我的答案不正确。我认为我们想忽略最后一个值,因为它不再改变,但如果我们想包含它,我们认为最简单的方法是在前导函数中设置一个默认值而不是 NA 并创建一个不匹配

> v[v!=lead(v, default = Inf)]
[1] 1 2 1 2 1 2 1

【讨论】:

  • 当我运行它时,我得到1 2 1 2 1 2 而不是1 2 1 2 1 2 1 按要求。为什么这是公认的答案?
  • 我编辑了我的答案。对于不会引发错误但会造成不匹配的默认值,是否有比 Inf 更好的选择?
【解决方案2】:
library(dplyr)
v <- c(1,1,1,2,2,2,1,1,1,2,1,1,2,2,2,2,2,1,1,1)

这两种解决方案是等价的。他们的问题是忽略了最后一个数字。

v[v != lead(v)] %>% head(-1)
#> [1] 1 2 1 2 1 2
v[v != v[c(2:length(v), NA)]] |> head(-1)
#> [1] 1 2 1 2 1 2

原因是因为最后一个比较是 1 != NA,当我们需要 TRUE 时它返回 NA。如果我们把它改成这样,它就可以工作了:

v[!mapply(identical, v, lead(v))]
#> [1] 1 2 1 2 1 2 1
v[!mapply(identical, v, v[c(2:length(v), NA)])]
#> [1] 1 2 1 2 1 2 1

不过,最简单且可能最快的解决方案是 @Chris 建议的 rle(v)$values

rle(v)$values
#> [1] 1 2 1 2 1 2 1

library(microbenchmark)
microbenchmark(
  v[!mapply(identical, v, lead(v))],
  v[!mapply(identical, v, v[c(2:length(v), NA)])],
  rle(v)$values
)
#> Unit: microseconds
#>                                             expr  min    lq   mean median   uq    max neval
#>                v[!mapply(identical, v, lead(v))] 63.0 65.95 68.308  67.70 69.2  115.5   100
#>  v[!mapply(identical, v, v[c(2:length(v), NA)])] 36.7 37.70 38.993  38.20 39.4   65.5   100
#>                                    rle(v)$values 11.1 12.80 14.472  14.45 15.8   32.4   100

reprex package 创建于 2022-06-10 (v2.0.1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 2014-02-19
    相关资源
    最近更新 更多