假设我有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
答案 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