【问题标题】:R - Removing rows from one table based on unique combination from another tableR - 根据另一个表中的唯一组合从一个表中删除行
【发布时间】:2021-06-14 14:16:55
【问题描述】:

我有两张桌子。 表 A - 包含完整数据的基表。 表 B - 包含按组合(始发地-目的地-承运人-等级)分组的数据。它只有那些既有豪华舱又有经济舱的组合,而且每个组合也有超过 100 名乘客。

我的目标是仅包含表 A 中与表 B 中的组合相关的那些行。 示例表如下 -

表 A

ItinID Origin Destination Carrier Class Fare
1 AB BC Delta Econ 100
2 AB BC Delta Premium 500
3 CD DE American Econ 200
4 EF FG United Econ 200
5 AB BC Delta Econ 150
6 AB BC Delta Premium 700

表 B

Origin Destination Carrier Class
AB BC Delta Econ
AB BC Delta Premium

我需要的输出表是-

ItinID Origin Destination Carrier Class Fare
1 AB BC Delta Econ 100
2 AB BC Delta Premium 500
5 AB BC Delta Econ 150
6 AB BC Delta Premium 700

另外,有没有办法完全跳过制作表B,直接对表A运行操作以获得输出表?

谢谢

【问题讨论】:

  • 有不同的方式来完成任务。如果您想更频繁地执行该任务,我建议您编写一个函数。其中包含 dplyr 命令和可以放入的变量,例如:Myfunc

标签: r


【解决方案1】:

1) 以下是基本、dplyr 和 sqldf 解决方案。我们连接 A 和 B,然后按 ItinID 排序(尽管 dplyr 解决方案似乎已经按这种方式排序,所以我们省略了这部分)。

m <- merge(A, B)
m[order(m$ItinID), names(A)]
##   ItinID Origin Destination Carrier   Class Fare
## 1      1     AB          BC   Delta    Econ  100
## 3      2     AB          BC   Delta Premium  500
## 2      5     AB          BC   Delta    Econ  150
## 4      6     AB          BC   Delta Premium  700

library(dplyr)
semi_join(A, B)
## Joining, by = c("Origin", "Destination", "Carrier", "Class")
##    ItinID Origin Destination Carrier   Class Fare
##  1      1     AB          BC   Delta    Econ  100
##  2      2     AB          BC   Delta Premium  500
##  3      5     AB          BC   Delta    Econ  150
##  4      6     AB          BC   Delta Premium  700

library(sqldf)   
sqldf("select A.* from B natural join A order by ItinID")
##   ItinID Origin Destination Carrier   Class Fare
## 1      1     AB          BC   Delta    Econ  100
## 2      2     AB          BC   Delta Premium  500
## 3      5     AB          BC   Delta    Econ  150
## 4      6     AB          BC   Delta Premium  700

2) 如果没有 B,我们可以使用来自 base 或 dplyr 的 filter 或 sql 中相关子查询的 bysubset

do.call("rbind", by(A, A[c("Origin", "Destination", "Carrier")], subset, 
  all(c("Econ", "Premium") %in% Class) & all(Fare >= 100)))
##   ItinID Origin Destination Carrier   Class Fare
## 1      1     AB          BC   Delta    Econ  100
## 2      2     AB          BC   Delta Premium  500
## 5      5     AB          BC   Delta    Econ  150
## 6      6     AB          BC   Delta Premium  700

library(dplyr)
A %>%
  group_by(Origin, Destination, Carrier) %>%
  filter(all(c("Econ", "Premium") %in% Class) & all(Fare >= 100)) %>%
  ungroup
## # A tibble: 4 x 6
##   ItinID Origin Destination Carrier Class    Fare
##   <chr>  <chr>  <chr>       <chr>   <chr>   <int>
## 1 1      AB     BC          Delta   Econ      100
## 2 2      AB     BC          Delta   Premium   500
## 3 5      AB     BC          Delta   Econ      150
## 4 6      AB     BC          Delta   Premium   700

library(sqldf)
cond <- "x.Origin = y.Origin and x.Destination = y.Destination and
  x.Carrier = y.Carrier"
fn$sqldf("select * from A x where 
    'Econ' in (select Class from A y where $cond) and 
    'Premium' in (select Class from A y where $cond) and
    100 <= (select min(Fare) from A y where $cond)")
##   ItinID Origin Destination Carrier   Class Fare
## 1      1     AB          BC   Delta    Econ  100
## 2      2     AB          BC   Delta Premium  500
## 3      5     AB          BC   Delta    Econ  150
## 4      6     AB          BC   Delta Premium  700

【讨论】:

    猜你喜欢
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多