【发布时间】:2014-05-18 13:14:11
【问题描述】:
从我的问题 here 开始,我试图在 R 中复制 Stata 命令 duplicates tag 的功能,它允许我标记数据集中根据给定的一组重复的行变量:
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
编辑
这是 Stata 产生的(应@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
请注意,(f1, f2, f3, f4) = (1, 1, 1, 3) 有两行,这两行都标记为dupvar = 1。同样,对于 (f1, f2, f3, f4) =(1, 1, 1, 8) 重复的两行。
R:
基本函数duplicated 仅标记第二个重复项。因此,我编写了一个函数来复制 R 中的 Stata 功能,使用 ddply。
# 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)
但正如在链接的问题中一样,性能是一个大问题。 Another possible solution是
dfDup$dup = duplicated(dfDup[, indexVars]) |
duplicated(dfDup[, indexVars], fromLast = TRUE)
dfDupSorted = with(dfDup, dfDup[order(eval(parse(text = indexVars))), ])
我有几个问题:
1. 是否可以让ddply版本更快?
2.第二个版本使用duplicated是否正确?对于重复行的两个以上副本?
3. 我将如何使用data.table 做到这一点?那会更快吗?
【问题讨论】:
-
@Arun 我不想采取任何行动 -- 我想创建一个指标来识别由一组变量标识的同质组。
-
@Arun 已添加示例输出。
-
你可以通过
ave(1:nrow(dd), dd[, 1:4], FUN = function(x) length(x) > 1)获得dupvar
标签: r data.table plyr stata