给重复行分配唯一标识符

4

如果我有一个类似下面这样的数据框:

x y
13 a
14 b
15 c
15 c
14 b

我希望每组相等的行都有一个唯一的ID,像这样:

x y id
13 a 1
14 b 2
15 c 3
15 c 3
14 b 2

有没有简单的方法来做到这一点?

谢谢


你的示例是否过于简单或包含打字错误,因为这里的id与x完全相同? - Jouni Helske
也许我的例子有点误导人,我会更改它! - Omar Wagih
使用data.table的类似问题:https://dev59.com/Mmcs5IYBdhLWcg3wPxge - flodel
@by0,请检查我的改进方案,它使用了interaction函数而不是paste0 - Jouni Helske
2个回答

4

我对paste0方法有些担忧。如果你的列包含更复杂的数据,可能会得到令人惊讶的结果。例如:

 x  y
ab  c
 a bc

一种解决方法是用paste(..., sep = "@")替换paste0(...)。即便如此,你也无法想出一个通用的sep,它将适用于任何类型的数据,因为sep始终有可能包含在某些数据中。
更为健壮的方法是使用拆分/转换/合并方法。你可以使用base包,但使用plyr会更容易一些:
library(plyr)
.idx <- 0L
ddply(df, colnames(df), transform, id = (.idx <<- .idx + 1L))    

如果速度太慢,我建议采用 data.table 方法,就像这里提出的那样:data.table "key indices" or "group counter"

paste0 的确是个好方法,不过我添加了一个更好的解决方案,实际上比原来的答案更加简洁。 - Jouni Helske
@Hemmo。我认为使用interaction等同于使用paste(..., sep = '.'); 从理论上讲,它会遇到我所讨论的相同(不太可能的)问题。 - flodel
哦,是的,你说得对,它们实际上产生了相同的结果,但在你讨论的情况下,它们都能正确地工作,因为你会得到ab.ca.bc这两个不同的结果。我想这就是所需的。然而,paste0不能正常工作(如果不需要分隔符,则可以使用)。 - Jouni Helske

3

我的第一个想法是:

创建一个新变量,通过将两列的值连接为字符串来组合它们:

a<-paste0(z$x,z$y) #z is your data.frame

将此作为因素并将其与您的数据框结合起来:
```html 将此作为因素并将其与您的数据框结合起来: ```
cbind(z,id=factor(a,labels=1:length(unique(a))))

编辑:@flodel 担心使用 paste0,最好使用普通的 paste 或交互操作:

a<-interaction(z,drop=TRUE)
cbind(z,id=factor(a,labels=1:length(unique(a))))

假设您想要分离x=aby=cx=ay=bc。如果不是,请使用paste0


2
我将把a替换为do.call(paste0, z)。将1:length(unique(a))替换为seq_along(unique(a)) - Arun
好的建议,我从来没有记住过 seq_along,而 do.call 对我来说是新事物。谢谢。 - Jouni Helske

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接