Kennzeichnen Sie alle doppelten Zeilen in R wie in Stata

Nach meiner FrageHierIch versuche, die Funktionalität des Befehls Stata in R zu replizierenduplicates tag, mit dem ich alle Zeilen eines Datensatzes kennzeichnen kann, die in Bezug auf einen bestimmten Satz von Variablen doppelt vorhanden sind:

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
Bearbeiten

Folgendes produziert Stata (auf Anfrage von @ Arun hinzugefügt):

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

Beachten Sie, dass für(f1, f2, f3, f4) = (1, 1, 1, 3) Es gibt zwei Zeilen, und beide sind markiertdupvar = 1. Ähnliches gilt für die beiden Zeilen, für die Duplikate vorhanden sind(f1, f2, f3, f4) =(1, 1, 1, 8).

R:

Die Basisfunktionduplicated markiert nur das zweite Duplikat. Also habe ich eine Funktion geschrieben, um die Stata-Funktionalität in R zu replizierenddply.

# 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)

Aber wie bei der verknüpften Frage ist die Leistung ein großes Problem.Eine andere mögliche Lösung ist

dfDup$dup = duplicated(dfDup[, indexVars]) | 
  duplicated(dfDup[, indexVars], fromLast = TRUE) 
dfDupSorted = with(dfDup, dfDup[order(eval(parse(text = indexVars))), ])

Ich habe ein paar Fragen:
1. Ist es möglich das zu machen?ddply Version schneller?
2. Verwendet die zweite Versionduplicated richtig? Für mehr als zwei Kopien der duplizierten Zeilen? 3. Wie würde ich dies mit tundata.table? Wäre das schneller?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage