I have two data frames: (these are shortened versions of them)
A
Link VU U P
1 DVH1 7 1 37
2 DVH2 7 0 38
3 DVH3 10
Use this:
within(merge(A,B,by="Link"), {
VU <- VU.x - VU.y
U <- U.x - U.y
P <- P.x - P.y
})[,c("Link","VU","U","P")]
EDIT: Bonus: if there are too many paired columns (not just VU, U and P) you can use this:
M <- merge(A,B,by="Link")
S <- M[,grepl("*\\.x$",names(M))] - M[,grepl("*\\.y$",names(M))]
cbind(M[,1,drop=FALSE],S)
# Link VU.x U.x P.x
#1 DVH1 5 1 22
#2 DVH2 3 0 24
#3 DVH3 10 1 30
A faster way than merge
(most likely) is to just make sure the second data.frame
is in the same row and column order as the first and subtract them from each other:
z <- names(A)[-1]
cbind(A[1], A[z] - B[match(A$Link, B$Link), z])
# Link VU U P
# 1 DVH1 5 1 22
# 2 DVH2 3 0 24
# 3 DVH3 10 1 30
Here's some sample data:
A <- structure(list(Link = c("DVH1", "DVH2", "DVH3"), VU = c(7L, 7L,
10L), U = c(1L, 0L, 1L), P = c(37L, 38L, 35L)), .Names = c("Link",
"VU", "U", "P"), class = "data.frame", row.names = c("1", "2", "3"))
B <- structure(list(Link = c("DVH1", "DVH3", "DVH2"), P = c(15L, 5L,
14L), U = c(0L, 0L, 0L), VU = c(2L, 0L, 4L)), .Names = c("Link",
"P", "U", "VU"), class = "data.frame", row.names = c("1", "3", "2"))