如何在 R 中对数据 table 行进行子集化以获取其自身唯一的行
How do I subset a data table row in R to get the rows unique to itself
我知道这可能是一个简单的问题,但我似乎做不对。
我有两个数据tables数据tableold_dt和数据tablenew_dt。两个数据 tables 都有两个相似的列。我的目标是从 new_dt 中获取不在 old_dt 中的行。
这是一个例子。 Old_dt
v1 v2
1 a
2 b
3 c
4 d
这里是new_dt
v1 v2
3 c
4 d
5 e
我想要的只是第 5 行。
使用setdiff没有用,因为我的真实数据超过了300万行。像这样使用子集
sub.cti <- subset(new_dt, old_dt$v1 != new_dt$v1 & old_dt$v2!= new_dt$v2)
仅导致 new_dt 本身。
使用
sub.cti <- subset(new_dt, old_dt$v1 != new_dt$v1 & old_dt$v2!= new_dt$v2)
一无所获。
使用
sub.cti <- new_dt[,.(!old_dt$v1, !old_dt$v2)]
导致多行错误
有人可以帮助我吗?
提前致谢
编辑:我注意到 OP 想要两行而不是只有一行来匹配。我将在此处保留解决方案的数据初始化部分,因为它在上面由 @akron 引用。但是,请使用@akrun 发布的最佳解决方案。就是比较多的"data.table way".
df1 <- data.table(a = 1:5, b = 6:10)
df2 <- data.table(a = c(1, 2, 3, 6, 7), b = 11:15)
head(df1)
a b
1: 1 6
2: 2 7
3: 3 8
4: 4 9
5: 5 10
head(df2)
a b
1: 1 11
2: 2 12
3: 3 13
4: 6 14
5: 7 15
我们可以做一个join
(数据来自@giraffehere's post)
df2[!df1, on = "a"]
# a b
#1: 6 14
#2: 7 15
根据 'a' 列获取 'df1' 中不在 'df2' 中的行
df1[!df2, on = "a"]
# a b
#1: 4 9
#2: 5 10
在 OP 的示例中,我们需要加入 on
两列
new_dt[!old_dt, on = c("v1", "v2")]
# v1 v2
#1: 5 e
注意:这里我假设 'new_dt' 和 'old_dt' 为 data.table
s.
当然,dplyr
是个不错的包。为了解决这个问题,可以使用更短的anti_join
library(dplyr)
anti_join(new_dt, old_dt)
# v1 v2
# (int) (chr)
#1 5 e
或 dplyr
中的 setdiff
可以在 data.frame
、data.table
、tbl_df
等
上工作
setdiff(new_dt, old_dt)
# v1 v2
#1: 5 e
但是,问题被标记为 data.table
。
如果 a 列有重复,您可以试试这个基本的 R hack:
id.var1 <- paste(df1$a, df1$b,sep="_")
id.var2 <- paste(df2$a, df2$b,sep="_")
dfKeep <- df[!(id.var2 %in% id.var1),]
dplyr 在您处理 R 中的表格数据时会有很大帮助 - 建议您了解有关 dplyr 的更多信息 here
library(dplyr)
library(magrittr) # this is just for shorter code with %<>%
# Create a sequence number that combine v1 & v2
Old_dt %<>%
mutate(sequence = paste0(v1,v2))
new_dt %<>%
mutate(sequence = paste0(v1,v2))
# Filter new_dt by sequence not existed in old_dt
result <- new_dt %>%
filter(!(sequence %in% Old_dt$sequence)) %>%
select(v1:v2)
v1 v2
5 e
我知道这可能是一个简单的问题,但我似乎做不对。
我有两个数据tables数据tableold_dt和数据tablenew_dt。两个数据 tables 都有两个相似的列。我的目标是从 new_dt 中获取不在 old_dt 中的行。
这是一个例子。 Old_dt
v1 v2
1 a
2 b
3 c
4 d
这里是new_dt
v1 v2
3 c
4 d
5 e
我想要的只是第 5 行。
使用setdiff没有用,因为我的真实数据超过了300万行。像这样使用子集
sub.cti <- subset(new_dt, old_dt$v1 != new_dt$v1 & old_dt$v2!= new_dt$v2)
仅导致 new_dt 本身。
使用
sub.cti <- subset(new_dt, old_dt$v1 != new_dt$v1 & old_dt$v2!= new_dt$v2)
一无所获。
使用
sub.cti <- new_dt[,.(!old_dt$v1, !old_dt$v2)]
导致多行错误
有人可以帮助我吗?
提前致谢
编辑:我注意到 OP 想要两行而不是只有一行来匹配。我将在此处保留解决方案的数据初始化部分,因为它在上面由 @akron 引用。但是,请使用@akrun 发布的最佳解决方案。就是比较多的"data.table way".
df1 <- data.table(a = 1:5, b = 6:10)
df2 <- data.table(a = c(1, 2, 3, 6, 7), b = 11:15)
head(df1)
a b
1: 1 6
2: 2 7
3: 3 8
4: 4 9
5: 5 10
head(df2)
a b
1: 1 11
2: 2 12
3: 3 13
4: 6 14
5: 7 15
我们可以做一个join
(数据来自@giraffehere's post)
df2[!df1, on = "a"]
# a b
#1: 6 14
#2: 7 15
根据 'a' 列获取 'df1' 中不在 'df2' 中的行
df1[!df2, on = "a"]
# a b
#1: 4 9
#2: 5 10
在 OP 的示例中,我们需要加入 on
两列
new_dt[!old_dt, on = c("v1", "v2")]
# v1 v2
#1: 5 e
注意:这里我假设 'new_dt' 和 'old_dt' 为 data.table
s.
当然,dplyr
是个不错的包。为了解决这个问题,可以使用更短的anti_join
library(dplyr)
anti_join(new_dt, old_dt)
# v1 v2
# (int) (chr)
#1 5 e
或 dplyr
中的 setdiff
可以在 data.frame
、data.table
、tbl_df
等
setdiff(new_dt, old_dt)
# v1 v2
#1: 5 e
但是,问题被标记为 data.table
。
如果 a 列有重复,您可以试试这个基本的 R hack:
id.var1 <- paste(df1$a, df1$b,sep="_")
id.var2 <- paste(df2$a, df2$b,sep="_")
dfKeep <- df[!(id.var2 %in% id.var1),]
dplyr 在您处理 R 中的表格数据时会有很大帮助 - 建议您了解有关 dplyr 的更多信息 here
library(dplyr)
library(magrittr) # this is just for shorter code with %<>%
# Create a sequence number that combine v1 & v2
Old_dt %<>%
mutate(sequence = paste0(v1,v2))
new_dt %<>%
mutate(sequence = paste0(v1,v2))
# Filter new_dt by sequence not existed in old_dt
result <- new_dt %>%
filter(!(sequence %in% Old_dt$sequence)) %>%
select(v1:v2)
v1 v2
5 e