sublime resaltar repetidos repetidas parrafos palabras encontrar eliminar duplicados duplicado datos como buscar borrar r loops apply lag

resaltar - encontrar palabras repetidas en word



Eliminar/contraer valores duplicados consecutivos en secuencia (4)

Con base R, me gustan los algoritmos divertidos:

x <- c("a", "a", "a", "b", "c", "c", "d", "e", "a", "a", "b", "b", "b", "e", "e", "d", "d") x[x!=c(x[-1], FALSE)] #[1] "a" "b" "c" "d" "e" "a" "b" "e" "d"

Tengo el siguiente marco de datos :

a a a b c c d e a a b b b e e d d

El resultado requerido debe ser

a b c d e a b e d

Esto significa que no hay dos filas consecutivas deben tener el mismo valor. Cómo se puede hacer sin usar bucle.

Como mi conjunto de datos es bastante grande, los ciclos tardan mucho tiempo en ejecutarse.

La estructura del marco de datos es como la siguiente

a 1 a 2 a 3 b 2 c 4 c 1 d 3 e 9 a 4 a 8 b 10 b 199 e 2 e 5 d 4 d 10

Resultado:

a 1 b 2 c 4 d 3 e 9 a 4 b 10 e 2 d 4

Debe eliminar toda la fila.


Por mucho que me guste, ... errr, love rle , aquí hay un juego de disparos:

EDIT: No puedo averiguar exactamente qué pasa con dplyr así que usé dplyr::lead . Estoy en OSX, R3.1.2, y la última dplyr de CRAN.

xlet<-sample(letters,1e5,rep=T) rleit<-function(x) rle(x)$values lagit<-function(x) x[x!=lead(x, default=1)] tailit<-function(x) x[x!=c(tail(x,-1), tail(x,1))] microbenchmark(rleit(xlet),lagit(xlet),tailit(xlet),times=20) Unit: milliseconds expr min lq median uq max neval rleit(xlet) 27.43996 30.02569 30.20385 30.92817 37.10657 20 lagit(xlet) 12.44794 15.00687 15.14051 15.80254 46.66940 20 tailit(xlet) 12.48968 14.66588 14.78383 15.32276 55.59840 20


Una forma fácil es usar rle :

Aquí están sus datos de muestra:

x <- scan(what = character(), text = "a a a b c c d e a a b b b e e d d") # Read 17 items

rle devuelve una list con dos valores: la longitud de ejecución (" lengths ") y el valor que se repite para esa ejecución (" values ").

rle(x)$values # [1] "a" "b" "c" "d" "e" "a" "b" "e" "d"

Actualización: Para un data.frame

Si está trabajando con un data.frame , intente algo como lo siguiente:

## Sample data mydf <- data.frame( V1 = c("a", "a", "a", "b", "c", "c", "d", "e", "a", "a", "b", "b", "e", "e", "d", "d"), V2 = c(1, 2, 3, 2, 4, 1, 3, 9, 4, 8, 10, 199, 2, 5, 4, 10) ) ## Use rle, as before X <- rle(mydf$V1) ## Identify the rows you want to keep Y <- cumsum(c(1, X$lengths[-length(X$lengths)])) Y # [1] 1 4 5 7 8 9 11 13 15 mydf[Y, ] # V1 V2 # 1 a 1 # 4 b 2 # 5 c 4 # 7 d 3 # 8 e 9 # 9 a 4 # 11 b 10 # 13 e 2 # 15 d 4

Actualización 2

El paquete "data.table" tiene una función rleid que le permite hacer esto con bastante facilidad. Usando mydf desde arriba, intente:

library(data.table) as.data.table(mydf)[, .SD[1], by = rleid(V1)] # rleid V2 # 1: 1 1 # 2: 2 2 # 3: 3 4 # 4: 4 3 # 5: 5 9 # 6: 6 4 # 7: 7 10 # 8: 8 2 # 9: 9 4


library(dplyr) x <- c("a", "a", "a", "b", "c", "c", "d", "e", "a", "a", "b", "b", "b", "e", "e", "d", "d") x[x!=lag(x, default=1)] #[1] "a" "b" "c" "d" "e" "a" "b" "e" "d"

EDITAR : para data.frame

mydf <- data.frame( V1 = c("a", "a", "a", "b", "c", "c", "d", "e", "a", "a", "b", "b", "e", "e", "d", "d"), V2 = c(1, 2, 3, 2, 4, 1, 3, 9, 4, 8, 10, 199, 2, 5, 4, 10), stringsAsFactors=FALSE)

La solución dplyr es un trazador de líneas:

mydf %>% filter(V1!= lag(V1, default="1")) # V1 V2 #1 a 1 #2 b 2 #3 c 4 #4 d 3 #5 e 9 #6 a 4 #7 b 10 #8 e 2 #9 d 4

post scriptum

lead(x,1) sugerida por @Carl Witthoft itera en orden inverso.

leadit<-function(x) x!=lead(x, default="what") rows <- leadit(mydf[ ,1]) mydf[rows, ] # V1 V2 #3 a 3 #4 b 2 #6 c 1 #7 d 3 #8 e 9 #10 a 8 #12 b 199 #14 e 5 #16 d 10