我有一个data.table
表,大约有250万行。有两列。我想删除两列中重复的任何行。以前对于data.frame,我会这样做:
df -> unique(df[,c('V1', 'V2')])
但这不适用于data.table。我试过unique(df[,c(V1,V2), with=FALSE])
但它似乎仍然只对data.table的键进行操作而不是整行。
有什么建议吗?
干杯, 戴维
实施例
>dt
V1 V2
[1,] A B
[2,] A C
[3,] A D
[4,] A B
[5,] B A
[6,] C D
[7,] C D
[8,] E F
[9,] G G
[10,] A B
在上面的data.table中V2
是表键,只删除行4,7和10。
> dput(dt)
structure(list(V1 = c("B", "A", "A", "A", "A", "A", "C", "C",
"E", "G"), V2 = c("A", "B", "B", "B", "C", "D", "D", "D", "F",
"G")), .Names = c("V1", "V2"), row.names = c(NA, -10L), class = c("data.table",
"data.frame"), .internal.selfref = <pointer: 0x7fb4c4804578>, sorted = "V2")
答案 0 :(得分:78)
之前的v1.9.8
从?unique.data.table
开始,很明显,在数据表上调用unique
仅适用于密钥。这意味着您必须在调用unique
之前将密钥重置为所有列。
library(data.table)
dt <- data.table(
V1=LETTERS[c(1,1,1,1,2,3,3,5,7,1)],
V2=LETTERS[c(2,3,4,2,1,4,4,6,7,2)]
)
使用一列作为键调用unique
:
setkey(dt, "V2")
unique(dt)
V1 V2
[1,] B A
[2,] A B
[3,] A C
[4,] A D
[5,] E F
[6,] G G
适用于v1.9.8 +
来自?unique.data.table
默认情况下,正在使用所有列(与?unique.data.frame
一致)
unique(dt)
V1 V2
1: A B
2: A C
3: A D
4: B A
5: C D
6: E F
7: G G
或使用by
参数获取特定列的唯一组合(如之前使用的键一样)
unique(dt, by = "V2")
V1 V2
1: A B
2: A C
3: A D
4: B A
5: E F
6: G G
答案 1 :(得分:6)
使用您的示例data.table ...
> dt<-data.table(V1 = c("B", "A", "A", "A", "A", "A", "C", "C", "E", "G"), V2 = c("A", "B", "B", "B", "C", "D", "D", "D", "F", "G"))
> setkey(dt,V2)
考虑以下测试:
> haskey(dt) # obviously dt has a key, since we just set it
[1] TRUE
> haskey(dt[,list(V1,V2)]) # ... but this is treated like a "new" table, and does not have a key
[1] FALSE
> haskey(dt[,.SD]) # note that this still has a key
[1] TRUE
因此,您可以列出表格的列,然后获取表格的unique()
,而无需将密钥设置为所有列或将其删除(通过将其设置为NULL
)as来自@Andrie的解决方案所需(并由@MatthewDowle编辑)。 @Pop和@Rahul建议的解决方案对我不起作用。
请参阅下面的尝试3,这与您最初的尝试非常相似。你的例子不清楚所以我不确定它为什么不起作用。也就是几个月前你发布了这个问题,所以也许data.table
被更新了?
> unique(dt) # Try 1: wrong answer (missing V1=C and V2=D)
V1 V2
1: B A
2: A B
3: A C
4: A D
5: E F
6: G G
> dt[!duplicated(dt)] # Try 2: wrong answer (missing V1=C and V2=D)
V1 V2
1: B A
2: A B
3: A C
4: A D
5: E F
6: G G
> unique(dt[,list(V1,V2)]) # Try 3: correct answer; does not require modifying key
V1 V2
1: B A
2: A B
3: A C
4: A D
5: C D
6: E F
7: G G
> setkey(dt,NULL)
> unique(dt) # Try 4: correct answer; requires key to be removed
V1 V2
1: B A
2: A B
3: A C
4: A D
5: C D
6: E F
7: G G
答案 2 :(得分:1)
unique(df)
适用于您的示例。
答案 3 :(得分:0)
这应该为您工作
dt <- unique(dt, by = c('V1, 'V2'))
答案 4 :(得分:0)
可以使用data.table记法:
unique(df[, .(V1, V2, V3), nomatch=0 ])
如此处https://stackoverflow.com/a/31875208/10087503
我没有比较这个版本与Magma版本的速度。