5

这是我的第一篇文章,我是编程和 R 的新手。

我正在尝试创建一个新列来标记或标记单独列中顺序重复的值。

df <- c(2,2,2,2,3,4,3,4,3,4,2,3,7,7,7))

使用复制函数返回以下内容:

data.frame(值 = df,标志 = 重复(df))

   value  flag  
1      2  FALSE  
2      2  TRUE  
3      2  TRUE  
4      2  TRUE  
5      3  FALSE  
6      4  FALSE  
7      3  TRUE  
8      4  TRUE  
9      3  TRUE  
10     4  TRUE  
11     2  TRUE  
12     3  TRUE  
13     7  FALSE  
14     7  TRUE  
15     7  TRUE   

我想要的是:

   value  flag  
1      2  TRUE  
2      2  TRUE  
3      2  TRUE  
4      2  TRUE  
5      3  FALSE  
6      4  FALSE  
7      3  FALSE  
8      4  FALSE  
9      3  FALSE  
10     4  FALSE  
11     2  FALSE  
12     3  FALSE  
13     7  TRUE    
14     7  TRUE    
15     7  TRUE     

我的数据集有超过 200 万个观测值,因此理想情况下该解决方案将是有效的。

谢谢你,约翰

4

2 回答 2

8

rle将让你得到你所追求的rep

rl <- rle( df )
rep( rl$lengths != 1 , times = rl$lengths )
#  [1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE
# [15]  TRUE

而且我相信rle是相当有效的。

2e6 长度向量上的时序(MBP 2008 年末):

system.time({ rl <- rle( df )
res <- rep( rl$lengths != 1 , times = rl$lengths )
 })
#   user  system elapsed 
#  0.449   0.106   0.559
于 2013-06-27T20:40:54.003 回答
2

既然你有超过 200 万,我建议你真的切换到data.table. 这里我的解决方案使用rle类似于@Simon 之一,我只写它的data.table版本。我相信这并不总是很明显,尤其是对于初学者(比如我在 data.table 下)。

library(data.table)
set.seed(1234)
dd <- sample(1:20, 2e+06, rep = TRUE)
DT <- data.table(dd)
system.time(DT[, `:=`(grp2, {
                            dd.rle = rle(dd)  ## store rle to not call it twice
                            rep(dd.rle$lengths > 1, times = dd.rle$lengths)
             })])
##    user  system elapsed 
##    1.17    0.06    1.28
##    user  system elapsed  <- rle twice
##    1.69    0.11    1.86

##        dd  grp2
## 1e+00:  3 FALSE
## 2e+00: 13  TRUE
## 3e+00: 13  TRUE
## 4e+00: 13  TRUE
## 5e+00: 18 FALSE
##    ---         
## 2e+06:  6 FALSE
## 2e+06:  5 FALSE
## 2e+06:  4 FALSE
## 2e+06: 10 FALSE
## 2e+06: 13 FALSE
于 2013-06-27T21:09:53.107 回答