Я думаю, здесь могут быть дыры в логике c, но я приведу некоторые предположения:
nrow(A)
всегда кратно nrow(B)
; это означает, что A[1,]
соединяется только с B[1,]
, A[2,]
с B[2,]
, ..., A[4,]
с B[1,]
, A[5,]
с B[2,]
, et c. - критерий сравнения - это "равенство общих столбцов"
Если это так, то
incommon <- intersect(colnames(A), colnames(B))
incommon
# [1] "BSTN" "ASTN" "ASTN1" "BSTN2" "ASTN2" "BSTN3" "ASTN3" "BSTN4" "ASTN4" "BSTN5"
# [11] "tr_in" "tr_out"
Bplus <- do.call(rbind.data.frame,
c(replicate(nrow(A) / nrow(B), B, simplify = FALSE),
list(stringsAsFactors = FALSE)))
Bplus
# BSTN tr_in ASTN1 BSTN2 ASTN2 BSTN3 ASTN3 BSTN4 ASTN4 BSTN5 ASTN tr_out
# 1 150 0 0 0 0 0 0 0 0 0 151 0
# 2 150 426 422 205 0 0 0 0 0 0 151 201
# 3 150 4201 4203 239 0 0 0 0 0 0 151 201
# 11 150 0 0 0 0 0 0 0 0 0 151 0
# 21 150 426 422 205 0 0 0 0 0 0 151 201
# 31 150 4201 4203 239 0 0 0 0 0 0 151 201
A$match <- +(rowSums(A[,incommon] == Bplus[,incommon]) == length(incommon))
A
# CARDID BSTN ASTN USERTYPE INVDIST INVTIME BSEC TRNID BSTN.r ASTN1 BSTN2 TRNID2 ASTN2
# 2406 5786 150 151 6 1100 340 21996 1672 150 0 0 0 0
# 2406.1 5786 150 151 6 1100 340 21996 1672 150 0 0 0 0
# 2406.2 5786 150 151 6 1100 340 21996 1672 150 0 0 0 0
# 4037 9737 150 151 6 1100 320 20368 2191 150 0 0 0 0
# 4037.1 9737 150 151 6 1100 320 20368 2191 150 0 0 0 0
# 4037.2 9737 150 151 6 1100 320 20368 2191 150 0 0 0 0
# BSTN3 TRNID3 ASTN3 BSTN4 TRNID4 ASTN4 BSTN5 TRNID5 ASTN.r ASEC.r tr_in tr_out match
# 2406 0 0 0 0 0 0 0 0 151 22234 0 0 1
# 2406.1 0 0 0 0 0 0 0 0 151 22234 0 0 0
# 2406.2 0 0 0 0 0 0 0 0 151 22234 0 0 0
# 4037 0 0 0 0 0 0 0 0 151 20547 0 0 1
# 4037.1 0 0 0 0 0 0 0 0 151 20547 0 0 0
# 4037.2 0 0 0 0 0 0 0 0 151 20547 0 0 0
Использование +(...)
это трюк для преобразования logical
в integer
0 и 1. Сохранять $match
так же просто, как поле logical
, удалив эту часть назначения. (Я использовал его только потому, что у вас это было в предполагаемом выводе. Я предпочитаю logical
для собственного использования, поскольку 1
или 1L
подразумевает ординальность и возможно , что может быть больше двух значений из 0 и 1. В декларативном смысле logical
ясно заявляет, что вы ожидаете только FALSE
и TRUE
и, возможно, NA
, когда оно неопределенно.)
Также, rowSums(...) == length(incommon)
проверяет, что все общие поля идентичны. Другой способ вычислить это -
apply(A[,incommon] == Bplus[,incommon], 1, all)
, который может быть более интуитивным и / или декларативным. Выбор, который нужно использовать, во многом зависит от предпочтений и немного от производительности ... метод rowSums
немного быстрее, чем метод apply
.
Данные
A <- read.table(header = TRUE, stringsAsFactors = FALSE, text = "
CARDID BSTN ASTN USERTYPE INVDIST INVTIME BSEC TRNID BSTN.r ASTN1 BSTN2 TRNID2 ASTN2 BSTN3 TRNID3 ASTN3 BSTN4 TRNID4 ASTN4 BSTN5 TRNID5 ASTN.r ASEC.r tr_in tr_out
2406 5786 150 151 6 1100 340 21996 1672 150 0 0 0 0 0 0 0 0 0 0 0 0 151 22234 0 0
2406.1 5786 150 151 6 1100 340 21996 1672 150 0 0 0 0 0 0 0 0 0 0 0 0 151 22234 0 0
2406.2 5786 150 151 6 1100 340 21996 1672 150 0 0 0 0 0 0 0 0 0 0 0 0 151 22234 0 0
4037 9737 150 151 6 1100 320 20368 2191 150 0 0 0 0 0 0 0 0 0 0 0 0 151 20547 0 0
4037.1 9737 150 151 6 1100 320 20368 2191 150 0 0 0 0 0 0 0 0 0 0 0 0 151 20547 0 0
4037.2 9737 150 151 6 1100 320 20368 2191 150 0 0 0 0 0 0 0 0 0 0 0 0 151 20547 0 0")
B <- read.table(header = TRUE, stringsAsFactors = FALSE, text = "
BSTN tr_in ASTN1 BSTN2 ASTN2 BSTN3 ASTN3 BSTN4 ASTN4 BSTN5 ASTN tr_out
1 150 0 0 0 0 0 0 0 0 0 151 0
2 150 426 422 205 0 0 0 0 0 0 151 201
3 150 4201 4203 239 0 0 0 0 0 0 151 201")