我希望有人可以幫助我弄清楚如何在 中多次修改一個變數data.table,或者找到一種適用于大資料的類似方法。
我有一個帶有字串的資料集(地址是準確的,但確切的內容并不重要),例如:
library(data.table)
library(stringr)
# example addresses although you can imagine other types of strings here
addr <- data.table(street = c('1 main street',
'99 madison avenue',
'340 circle court'))
我有另一個資料集,其中有一列模式,我想在這些字串(即資料集中)中搜索模式,addr并用第二個資料集中另一列中保存的其他字串替換。例如:
# example of patterns to search for and what I want to replace them with
abbrev <- data.table(full = c('street', 'avenue', 'circle', 'court'),
abbrev = c('st', 'ave', 'cir', 'ct'))
實際的資料集要大得多:我要檢查每個地址的數百萬個地址和 300 多個縮寫。
在回圈中執行此操作相當簡單,但由于大小的原因,我想使用data.table并且可能使用一個apply函式來提高此程序的效率。
我正在努力弄清楚如何準確地寫這個。我想要以下內容:
# duplicate addresses so we can compare to changes
addr[, orig.street := street]
# function to substitute abbreviations we want
standardize <- function(word, shorter) {
addr[, street := str_replace_all(street,
paste0(" ", word),
paste0(" ", shorter))]
}
# now run function for all abbreviations we want
addr[, street := mapply(FUN = standardize,
word = abbrev$full,
shorter = abbrev$abbrev,
SIMPLIFY = FALSE, USE.NAMES = FALSE)]
當我在 Rstudio 中運行它時,這將回傳錯誤,“提供了 4 個專案以分配給列 'street' 的 3 個專案。RHS 長度必須為 1(單個值可以)或完全匹配 LHS 長度。如果如果您希望“回收”RHS,請明確使用 rep() 以向您的代碼讀者明確這一意圖。”
然而,它確實給了我我想要的東西,盡管有錯誤:
# it breaks but I do get the desired outcome:
street orig.street
1: 1 main st 1 main street
2: 99 madison ave 99 madison avenue
3: 340 cir ct 340 circle court
我覺得必須有一個我缺少的解決方案,但我還沒有弄清楚。任何幫助將不勝感激。
uj5u.com熱心網友回復:
您可以將其與庫stri_replace_all_fixed中的引數一起使用vectorize_all = FALSE(stringi):
library(data.table)
library(stringi)
addr <- data.table(orig_street = c('1 main street',
'99 madison avenue',
'340 circle court'))
abbrev <- data.table(full = c('street', 'avenue', 'circle', 'court'),
abbrev = c('st', 'ave', 'cir', 'ct'))
addr[, street := stri_replace_all_fixed(orig_street, abbrev$full, abbrev$abbrev, vectorize_all = FALSE)]
> addr
orig_street street
1: 1 main street 1 main st
2: 99 madison avenue 99 madison ave
3: 340 circle court 340 cir ct
另請參閱此相關答案并注意library(stringr)import library(stringi)。
uj5u.com熱心網友回復:
另一種Reduce方法是:
addr[, street2 := Reduce(function(txt, i) gsub(paste0("\\b", abbrev$full[i], "\\b"), abbrev$abbrev[i], txt),
seq_len(nrow(abbrev)), init = street)][]
# street street2
# <char> <char>
# 1: 1 main street 1 main st
# 2: 99 madison avenue 99 madison ave
# 3: 340 circle court 340 cir ct
筆記:
- 我明確地將單詞邊界 (
\\b) 添加到gsub正則運算式中,這樣我們就不會無意中替換單詞的一部分。我認為我們需要這個而不是fixed=TRUE因為gsub("court", "ct", "courteous", fixed = TRUE)回傳"cteous"。 - 如果我們嘗試一個
apply族(onabbrev),那么我們會看到每個模式的更新值,但不知道(無需額外作業)哪個模式發生了變化;此外,如果有可能(通常,可能不是這里)多個縮寫模式有用,那么我們需要將每個模式/替換應用于前一個替換的結果,這*apply不能(很容易)。 - 不幸的是,
Reduce它不容易迭代幀的行,所以我們迭代行索引 (seq_len(nrow(abbrev)))。
但是,我不禁覺得最后一排真的應該是"340 circle ct"。在這種情況下,如果我們假設縮寫在字串的末尾,我們可以使用它來代替:
addr[, street3 := Reduce(function(txt, i) gsub(paste0("\\b", abbrev$full[i], "\\s*$"), abbrev$abbrev[i], txt),
seq_len(nrow(abbrev)), init = street)][]
# street street2 street3
# <char> <char> <char>
# 1: 1 main street 1 main st 1 main st
# 2: 99 madison avenue 99 madison ave 99 madison ave
# 3: 340 circle court 340 cir ct 340 circle ct
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/410754.html
標籤:
上一篇:Java:搜索將文本拆分為單獨單詞的正則運算式,包括字母、數字和字母之間的'
下一篇:查找前半部分與后半部分匹配的字串
