考虑以下两个data.frames:
a1 <- data.frame(A = c(1:5, 2, 4, 2), B = letters[c(1:5, 2, 4, 2)])
a2 <- data.frame(A = c(1:3,2), B = letters[c(1:3,2)])
我想删除a1
中a2
的确切行,以便结果应为:
A B
4 d
5 e
4 d
2 b
请注意,a1中包含2 b
的一行将保留在最终结果中。目前,我使用循环语句,由于我的data.frames中有许多变量和数千行,因此变得非常慢。是否有任何内置函数可以获得此结果?
答案 0 :(得分:3)
这个想法是,为每个文件添加一个重复计数器,这样你就可以获得每一行的唯一匹配。数据表很好,因为很容易计算重复项(使用.N
),它还为集合操作提供了必要的函数(fsetdiff
)。
library(data.table)
a1 <- data.table(A = c(1:5, 2, 4, 2), B = letters[c(1:5, 2, 4, 2)])
a2 <- data.table(A = c(1:3,2), B = letters[c(1:3,2)])
# add counter for duplicates
a1[, i := 1:.N, .(A,B)]
a2[, i := 1:.N, .(A,B)]
# setdiff gets the exception
# "all = T" allows duplicate rows to be returned
fsetdiff(a1, a2, all = T)
# A B i
# 1: 4 d 1
# 2: 5 e 1
# 3: 4 d 2
# 4: 2 b 3
答案 1 :(得分:2)
您可以使用vendor.fa8737033d56bf5e7c33.bundle.js:17 ERROR TypeError: Cannot read property 'city' of undefined
at Object.eval [as updateDirectives] (e.ngfactory.js:163)
at Object.updateDirectives (vendor.fa8737033d56bf5e7c33.bundle.js:136)
at ur (vendor.fa8737033d56bf5e7c33.bundle.js:136)
at wr (vendor.fa8737033d56bf5e7c33.bundle.js:136)
at br (vendor.fa8737033d56bf5e7c33.bundle.js:136)
at ur (vendor.fa8737033d56bf5e7c33.bundle.js:136)
at wr (vendor.fa8737033d56bf5e7c33.bundle.js:136)
at br (vendor.fa8737033d56bf5e7c33.bundle.js:136)
at ur (vendor.fa8737033d56bf5e7c33.bundle.js:136)
at wr (vendor.fa8737033d56bf5e7c33.bundle.js:136)
执行此操作。我设置dplyr
以消除有关因素不匹配的警告。
stringsAsFactors = FALSE
修改强>
这是一个类似的解决方案,有点短。这将执行以下操作:(1)为行号添加一列以加入library(dplyr)
a1 <- data.frame(A = c(1:5, 2, 4, 2), B = letters[c(1:5, 2, 4, 2)], stringsAsFactors = FALSE)
a2 <- data.frame(A = c(1:3,2), B = letters[c(1:3,2)], stringsAsFactors = FALSE)
## Make temp variables to join on then delete later.
# Create a row number
a1_tmp <-
a1 %>%
group_by(A, B) %>%
mutate(tmp_id = row_number()) %>%
ungroup()
# Create a count
a2_tmp <-
a2 %>%
group_by(A, B) %>%
summarise(count = n()) %>%
ungroup()
## Keep all that have no entry int a2 or the id > the count (i.e. used up a2 entries).
left_join(a1_tmp, a2_tmp, by = c('A', 'B')) %>%
ungroup() %>% filter(is.na(count) | tmp_id > count) %>%
select(-tmp_id, -count)
## # A tibble: 4 x 2
## A B
## <dbl> <chr>
## 1 4 d
## 2 5 e
## 3 4 d
## 4 2 b
个项目(2)data.frame
(第二个a2
)中的临时列,该列将显示为null加入data.frame
(即表示它对a1
是唯一的。)
a1
我认为这个解决方案比第一个解决方案更简单(也许很少)。
答案 2 :(得分:1)
我想这与DWal's solution类似,但在基础R
中a1_temp = Reduce(paste, a1)
a1_temp = paste(a1_temp, ave(seq_along(a1_temp), a1_temp, FUN = seq_along))
a2_temp = Reduce(paste, a2)
a2_temp = paste(a2_temp, ave(seq_along(a2_temp), a2_temp, FUN = seq_along))
a1[!a1_temp %in% a2_temp,]
# A B
#4 4 d
#5 5 e
#7 4 d
#8 2 b
答案 3 :(得分:1)
这是dplyr
的另一个解决方案:
library(dplyr)
a1 %>%
arrange(A) %>%
group_by(A) %>%
filter(!(paste0(1:n(), A, B) %in% with(arrange(a2, A), paste0(1:n(), A, B))))
<强>结果:强>
# A tibble: 4 x 2
# Groups: A [3]
A B
<dbl> <fctr>
1 2 b
2 4 d
3 4 d
4 5 e
这种过滤方式可以避免创建额外的不需要的列,以后必须在最终输出中删除这些列。此方法还对输出进行排序。不确定它是不是你想要的。