SQL连接和选择的R数据帧等价

时间:2014-11-20 05:11:41

标签: sql r

假设我有2个数据帧A和B,它们都有c1,c2,c3作为列

我希望得到相同的

SELECT A.C1 AS "C1", A.C2 AS "C2", (A.C3 - B.C3) AS "C3"
FROM A
JOIN B
ON (A.C1 = B.C1) AND (A.C2 = B.C2);

如何在不使用for-loop的情况下在R中执行相同的操作?

编辑:添加示例

A
c1, c2, c3
1, 1, 3
1, 2, 4
1, 2, 5
2, 1, 5

B
c1, c2, c3
1, 1, 2
1, 2, 4
2, 1, 8

应该产生

c1, c2, c3
1, 1, 1
1, 2, 0
1, 2, 1
2, 1, -3

4 个答案:

答案 0 :(得分:5)

这是data.table替代方案。

A = read.table(text="c1, c2, c3
1, 1, 3
1, 2, 4
1, 2, 5
2, 1, 5", header=T, sep=",")

B = read.table(text="c1, c2, c3
1, 1, 2
1, 2, 4
2, 1, 8", header=T, sep=",")

setDT(A); setDT(B) # convert data frames to data tables
setkey(A, c1, c2) # key columns c1, c2 for "joining"
new_dt <- A[B][,list(c1,    # the operation
                     c2,
                     c3 = c3-i.c3)]
new_dt

# you get
   c1 c2 c3
1:  1  1  1
2:  1  2  0
3:  1  2  1
4:  2  1 -3

答案 1 :(得分:3)

这里有很多可能的答案,但这里只有一个(使用标准/基本功能):

> foo <- merge(x = A, y = B, by.x = c("c1", "c2"), by.y = c("c1", "c2"))
> foo$c3 <- foo$c3.x - foo$c3.y
> foo <- foo[c("c1", "c2", "c3")]

一般来说,merge(...)是您寻求复制类似SQL的连接的函数。

还要考虑使用允许直接在数据帧上使用SQL的R包,例如: sqldf包。

答案 2 :(得分:2)

使用sqldf的一种可能的解决方案:

install.packages("sqldf")
library(sqldf)
rs <- sqldf("select a.c1, a.c2, (a.c3 - b.c3) as c3
                from a
                join b
                on a.c1 = b.c1 and a.c2 = b.c2")

答案 3 :(得分:2)

这是dplyr可能性

left_join(A, B, c("c1", "c2")) %>% transmute(c1, c2, c3 = c3.x - c3.y)
#   c1 c2 c3
# 1  1  1  1
# 2  1  2  0
# 3  1  2  1
# 4  2  1 -3