Bạn có thể sử dụng dplyr
để làm điều này. Tôi đặt stringsAsFactors = FALSE
để loại bỏ cảnh báo về các yếu tố không khớp.
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
EDIT
Đây là một giải pháp tương tự đó là ngắn hơn một chút. Điều này thực hiện như sau: (1) thêm cột cho số hàng để tham gia cả hai data.frame
mục (2) cột tạm thời trong a2
(2nd data.frame
) sẽ hiển thị dưới dạng null trong tham gia a1
(nghĩa là chỉ có duy nhất a1
) .
library(dplyr)
left_join(a1 %>% group_by(A,B) %>% mutate(rn = row_number()) %>% ungroup(),
a2 %>% group_by(A,B) %>% mutate(rn = row_number(), tmpcol = 0) %>% ungroup(),
by = c('A', 'B', 'rn')) %>%
filter(is.na(tmpcol)) %>%
select(-tmpcol, -rn)
## # A tibble: 4 x 2
## A B
## <dbl> <chr>
## 1 4 d
## 2 5 e
## 3 4 d
## 4 2 b
Tôi nghĩ giải pháp này đơn giản hơn một chút (có lẽ rất ít) so với phiên bản đầu tiên.
Nó không rõ ràng đầu ra của bạn là chính xác, '2b' là cả hai để bắt đầu, tôi thiếu cái gì? – steveb
@steveb '2b' là hai lần trong 'a1', vì vậy chỉ có một bị hủy và một vẫn ở đầu ra. –
Ahh, đó là những gì tôi nhận được để đọc quá nhanh. – steveb