這是對r - for回圈比較2個資料框架的所有行的跟進,但應用了不同的匹配函式(stringr::str_detect())。
我試圖將資料框架d1中的2列與資料框架d2中的2列進行逐行比較。為了說明這個問題,我創建了假的資料集:
d1 <- data.frame()
a = c("a"/span>。 "b"。
b = c("aa"。 "bbb", "ccc"。 "d")
)
d2 <- data.frame()
a = c("a"/span>。 "a"。 "d", "b"),
b = c("aaa"。 "bbb", "ddd"。 "bbb")
)
事實上,我想標記d1中的所有行,因為我可以在d2的至少一行中找到一個匹配。這就是我想要的結果:
output < -矩陣(nrow =nrow(d1)/span>。 ncol =nrow(d2))
for (i in 1: nrow(d1)) {
for (j in 1: nrow(d2)) {
output[i,j] = ifelse()
d1$a[i] == d2$a[j] & str_detect(d2$b[j], d1$b[i]),
1,
0)
}
}
d1$flag < - apply(output, 1,max)
d1
由于我的d1表的行數可能變得相當大,因此矩陣的大小也會變得很大。有沒有更好的方法來寫這個回圈,這樣我就可以用每行的最大值創建一個向量來代替矩陣,這樣記憶體就不會爆炸了。
uj5u.com熱心網友回復:
高效的連接
@Roland 暗示了一個好的解決方案。fuzzyjoin::fuzzy_*_join。它的唯一問題是它仍然是一個連接,而這是 OP 想要避免的......坦率地說,大多數的 merge 和 *_join 函式都是相對高效的,因為在對每一列進行爆炸性的比較之前就已經完成了;當約束太松并且接近于一個笛卡爾的連接時,效率就低了。
根據這一點,我將修改d2,以便我們至少有一個兩行的匹配:
d2 <- data.frame()
a = c("a"/span>。 "a"。 "d", "b", "b"),
b = c("aaa"。 "bbb"。 "ddd", "bbb"。 "bbb")
)
從這里開始,我們需要添加一個行的ID,加入,然后在這個行的ID上聚合。
d1$rowid < - seq_len(nrow(d1))
out <- fuzzyjoin:: fuzzy_left_join(d1,d2。 由= c("a"。 "b")。 match_fun = list(`==`。 Vectorize(grepl)))
出
# a.x b.x rowid a.y b.y
# 1 a aa 1 a aaa
# 2 b bbb 2 b bbb[/span]。
#3 b bbb 2 b bbb
# 4 c ccc 3 <NA> <NA>
# 5 d d 4 d ddd
這樣一來,注意到rowid 2有兩個出現(所以我們需要合并它們),而rowid 3是不匹配的。(題外話:fuzzyjoin by design會重復所有 "by "列。減少它們是很容易的,即使它看起來很奇怪。)
out2 <- aggregate(a.y ~ rowid a. x b.x, data = out, na。 動作 = na.pass, na.
FUN = function(z) sum(! is.na(z)))
names(out2)[-1] < - c("a"/span>。 "b", "flag")
輸出2
# rowid a b flag
# 1 1 a aa 1
# 2 2 b bbb 2
# 3 3 c ccc 0
# 4 4 d d 1
按行排列
如果這導致了記憶體問題,那么下一步將是對其中一個框架進行逐行處理。d1$flag < - mapply(function(A1, B1) sum(A1 == d2$a & grepl(B1, d2$b))。 d1$a, d1$b)
d1
# a b flag
# 1 a aa 1
# 2 b bbb 2
# 3 c ccc 0
# 4 d d 1
uj5u.com熱心網友回復:
想用str_detect和for loops創建一個解決方案,但說實話,它比這里和你的原帖中提供的解決方案效率低很多:
d1$flag <- 0
for (i in 1: nrow(d1)) {
flag <- list()
for (j in 1: nrow(d2)) {
flag<- rbind(flag, stringr:: str_detect(paste(d1[i。 1] 。 d1[i,2]) 。 粘貼(d2[j。 1] 。 d2[/span>j, 2])))
}
if (any(flag == TRUE)) {
d1[i, 3] < - 1
}
}
如果你不想使用列索引,你可以用"列名"來代替,只是要確保在它周圍加上引號,即d1[i, "flag"]。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/312045.html
標籤:
上一篇:用句號陳述句結束程式
