Etiquete todas las filas duplicadas en R como en Stata
Siguiendo mi preguntaaquí, Estoy tratando de replicar en R la funcionalidad del comando Stataduplicates tag
, lo que me permite etiquetar todas las filas de un conjunto de datos que están duplicadas en términos de un conjunto de variables dado:
clear *
set obs 16
g f1 = _n
expand 104
bys f1: g f2 = _n
expand 2
bys f1 f2: g f3 = _n
expand 41
bys f1 f2 f3: g f4 = _n
des // describe the dataset in memory
preserve
sample 10 // draw a 10% random sample
tempfile sampledata
save `sampledata', replace
restore
// append the duplicate rows to the data
append using `sampledata'
sort f1-f4
duplicates tag f1-f4, generate(dupvar)
browse if dupvar == 1 // check that all duplicate rows have been tagged
EditarEsto es lo que produce Stata (agregado en la solicitud de @ Arun):
f1 f2 f3 f4 dupvar
1 1 1 1 0
1 1 1 2 0
1 1 1 3 1
1 1 1 3 1
1 1 1 4 0
1 1 1 5 0
1 1 1 6 0
1 1 1 7 0
1 1 1 8 1
1 1 1 8 1
Tenga en cuenta que para(f1, f2, f3, f4) = (1, 1, 1, 3)
hay dos filas, y ambas están marcadasdupvar = 1
. Del mismo modo, para las dos filas que son duplicados para(f1, f2, f3, f4) =(1, 1, 1, 8)
.
La función baseduplicated
etiqueta solo el segundo duplicado en adelante. Entonces, escribí una función para replicar la funcionalidad Stata en R, usandoddply
.
# Values of (f1, f2, f3, f4) uniquely identify observations
dfUnique = expand.grid(f1 = factor(1:16),
f2 = factor(1:41),
f3 = factor(1:2),
f4 = factor(1:104))
# sample some extra rows and rbind them
dfDup = rbind(dfUnique, dfUnique[sample(1:nrow(dfUnique), 100), ])
# dummy data
dfDup$data = rnorm(nrow(dfDup))
# function: use ddply to tag all duplicate rows in the data
fnDupTag = function(dfX, indexVars) {
dfDupTag = ddply(dfX, .variables = indexVars, .fun = function(x) {
if(nrow(x) > 1) x$dup = 1 else x$dup = 0
return(x)
})
return(dfDupTag)
}
# test the function
indexVars = paste0('f', 1:4, sep = '')
dfTemp = fnDupTag(dfDup, indexVars)
Pero como en la pregunta vinculada, el rendimiento es un gran problema.Otra posible solución es
dfDup$dup = duplicated(dfDup[, indexVars]) |
duplicated(dfDup[, indexVars], fromLast = TRUE)
dfDupSorted = with(dfDup, dfDup[order(eval(parse(text = indexVars))), ])
Tengo algunas preguntas:
1. ¿Es posible hacer elddply
versión más rápida?
2. Es la segunda versión usandoduplicated
¿correcto? ¿Para más de dos copias de las filas duplicadas? 3. ¿Cómo haría esto usandodata.table
? ¿Sería eso más rápido?