我有一个如下数据数据框:
Data <- data.frame(
'id' = sample(1:30, 100, replace=T),
'first_name' = sample(c("John", "Alex", "Ben"), 100, replace =T),
'last_name' = sample(c("Bailey", "Smith", "Jones"), 100, replace =T),
'country' = sample(c("United Kingdom", "United States", "Canada"), 100, replace =T)
)
所以我知道我可以使用下面的方法来获取重复的first_names:
Data[duplicated(Data$first_name),]
但是,如何获得不同ID 的重复记录列表相同的名字,同一个昨晚和同一个国家?
所以理想的结果如下:
country id first_name last_name
United Kingdom 1 John Smith
United Kingdom 2 John Smith
United States 10 Alex Jones
United States 12 Alex Jones
答案 0 :(得分:3)
以下是使用data.table
的替代方法:
ans = unique(setDT(Data))
ans = ans[, list(id=id[.N > 1L]), by = list(first_name, last_name, country)]
setorder(ans, id)
首先,我们只得到整个data.table上的唯一行。
然后我们按照first_name
,last_name
和country
列进行分组,并仅保留id
在该群组中多次出现的行。
最后,我们使用函数setorder
按列ID重新排序ans
。
setorder
通过引用重新排序data.table 的行。它类似于base的顺序函数,但由于a)基数排序/排序而快得多)和2)就地修改对象(没有副本)。
对于熟悉setkey
的data.table用户,并问问题为什么不是setkey
:在这种情况下,两者之间的结果是相同的。但setkey
按升序排序总是,而会设置其他属性sorted
。这里的目标是重新排序行,而不是设置密钥(连接的要求)。因此,函数setorder
在这里更有意义。
setorder
也可以按升序和降序重新排序(尽管这里不相关)。
答案 1 :(得分:2)
可能有帮助:
Data <- unique(Data)
nm1 <- setdiff(names(Data), "id")
res <- do.call(rbind,
lapply(split(Data, as.character(interaction(Data[, nm1]))),function(x) {
x[duplicated(x[, nm1]) | duplicated(x[, nm1], fromLast = TRUE), ]
}))
row.names(res) <- NULL
答案 2 :(得分:2)
我愿意:
dup <- subset(unique(Data),
ave(id, country, first_name, last_name, FUN = length) > 1L)
其中unique
删除相同的人(相同的ID /国家/第一/最后),ave
计算共享国家/第一/最后一个人的数量。
然后,您可能会发现对数据进行排序以使重复项彼此相邻非常有用:
dup <- dup[with(dup, order(country, first_name, last_name, id)), ]
答案 3 :(得分:1)
dplyr
可能性:
library(dplyr)
Data %>%
group_by(first_name, last_name, country) %>%
mutate(n = n()) %>%
filter(n > 1) %>%
arrange(country, id)
答案 4 :(得分:0)
尝试:
> data.table(with(Data, table(id, paste(first_name, last_name, country))))[N>0][,.SD[.N>1],by=V1]
V1 id N
1: Alex Bailey Canada 2 2
2: Alex Bailey Canada 26 1
3: Alex Bailey United Kingdom 7 1
4: Alex Bailey United Kingdom 8 1
5: Alex Bailey United Kingdom 16 1
6: Alex Bailey United Kingdom 29 1
...