Не так эффективно, как у Akrun, но другое решение Base R:
# Reshape B from wide to long:
long_B <-
data.frame(
reshape(
B,
direction = "long",
varying = names(B)[names(B) != "Date"],
v.names = "Exchange",
idvar = "Date",
timevar = "Currency",
times = names(B)[names(B) != "Date"]
),
row.names = NULL
)
# Left join on intersecting vectors:
a_left_join_b <-
merge(A,
long_B,
by = intersect(colnames(A), colnames(long_B)),
all.x = TRUE)
Альтернатива в обратном направлении:
ab <-
B %>%
gather(key = "Currency", value = "Exchange", -Date) %>%
right_join(A, by = intersect(colnames(.), colnames(A)), all.y = TRUE)
Данные:
A <-
structure(
list(
TransactionNo = 1000001:1000006,
Date = as.POSIXct(
c(
"2019-07-01",
"2019-07-01",
"2019-07-03",
"2019-07-04",
"2019-07-05",
"2019-07-06"
),
tz = Sys.timezone()
),
AccountNo = c(10001L, 10001L, 10001L, 10001L, 10001L, 10001L),
TransactionType = c("Spend", "Spend", "Spend", "Spend", "Spend",
"Spend"),
Amount = c(-12.44, -31.92, -8.08, -6.02, -5.04, -8.43),
Currency = c("SGD", "CNY", "USD", "SGD", "USD", "SGD")
),
class = "data.frame",
row.names = c("1",
"2", "3", "4", "5", "6")
)
B <-
structure(
list(
Date = as.POSIXct(
c(
"2019-07-01 00:00:00",
"2019-07-02 00:00:00",
"2019-07-03 00:00:00",
"2019-07-04 00:00:00",
"2019-07-05 00:00:00",
"2019-07-06 00:00:00"
),
tz = Sys.timezone()
),
USD = c(1.35, 1.4, 1.36, 1.37, 1.38,
1.39),
CNY = c(0.198, 0.198, 0.197, 0.197, 0.197, 0.197),
SGD = c(1L,
1L, 1L, 1L, 1L, 1L)
),
class = "data.frame",
row.names = c("1",
"2", "3", "4", "5", "6")
)