簡體   English   中英

R sapply循環替換for循環

[英]R sapply loop to replace for loop

我之前已經成功地將for循環切換 sapply循環 ,而且我知道(system.time())它們更快。

但是我的思想仍然以for循環的方式工作...

請幫助我將其轉換為for循環大小寫:

names.list <- c("Anna", "Ana", "Albert", "Albort", "Rob", "Robb", "Tommy", "Tommie")
misspell.list <- c("Anna", "Albort", "Robb", "Tommie")
fix.list <- c("Ana", "Albert", "Rob", "Tommy")

for(i in 1:length(fix.list)) {
        names.list[which(names.list == misspell.list[i])] <- fix.list[i]

}

names.list

到sapply()

到目前為止,我得到了:

sapply(seq_along(fix.list), function(x)
        names.list[which(names.list == misspell.list[x])]  <- fix.list[x]
)

但這只會返回原始向量。

謝謝!

編輯1:

misspell.list和fix.list是由adist()波紋管自動創建的,原始的names.list具有665個元素。 我的for()解決方案返回length(unique(names.list)) = 653個元素

# will do another sapply() substitution here soon
for(i in 1:(length(names.list)-1)) {
        distancias[i] <- adist(names.list[i], names.list[i+1])
}

# fix list
misspell.list <- names.list[which(distancias < 2)]
fix.list <- names.list[which(distancias < 2) +1]

編輯2:謝謝你,現在我是一個apply的霸主 ,我在這里只是為了展示與adist()一起使用的其他for-apply替換

nomes <- sort(unique(names.list))
distancias <- rep(10, length(nomes))

#adist() for finding misspelling
sapply(seq_along(nomes), 
       function(x) {
                if(x<length(nomes)) {
                        distancias[x] <<- adist(nomes[x], nomes[x+1])
                        }
        }
       )
# fix list
misspell.list <- names.list[which(distancias < 2)]
fix.list <- names.list[which(distancias < 2) +1]

您已經知道的另一部分,再次感謝!

如果misspell.listfix.list之間存在一對一的對應關系, fix.list可以使用match函數消除循環

names.list[match(misspell.list,names.list)] <- fix.list

names.list
#[1] "Ana"    "Ana"    "Albert" "Albert" "Rob"    "Rob"    "Tommy"  "Tommy"

使用match的解決方案要好得多,但是就您要嘗試執行的操作而言,這將起作用。 首先,您不需要which 您還需要使用<<-運算符告訴循環中定義的內部函數使用全局環境,而不是其自己的局部環境-否則,它不會更改names.list ,而只會更改其副本。

sapply(seq_along(fix.list), function(x)
  names.list[names.list == misspell.list[x]]  <<- fix.list[x]
)

names.list
[1] "Ana"    "Ana"    "Albert" "Albert" "Rob"    "Rob"    "Tommy"  "Tommy" 

我會建議對您的整個設置進行一個小的更改。 當像您一樣使用索引時,需要確保順序始終相同。 如果添加或刪除名稱,則整個過程將分崩離析。

使用命名列表和lapplysapply ,您的代碼將保持動態,並且可以將多個拼寫錯誤與一個名稱匹配。

misspell.list  <-  list(
  'Anna' = 'Ana',
  'Albort' = 'Albert',
  'Robb' = 'Rob',
  'Tommie' = 'Tommy'
)

names.list <- c("Anna", "Ana", "Albert", "Albort", "Rob", "Robb", "Tommy", "Tommie")


> sapply(names.list,function(x) ifelse(x %in% names(misspell.list),misspell.list[[x]],x))
    Anna      Ana   Albert   Albort      Rob     Robb    Tommy   Tommie 
   "Ana"    "Ana" "Albert" "Albert"    "Rob"    "Rob"  "Tommy"  "Tommy" 

為了說明我的意思,我正在使用sample將您的names.list向量names.list並將其擴展為20個名稱。 這表明順序和長度沒有影響。

sapply(names.list[sample(1:length(names.list),20,replace = T)],function(x) ifelse(x %in% names(misspell.list),misspell.list[[x]],x))
  Albert   Tommie      Rob   Tommie      Rob    Tommy      Ana     Robb   Tommie      Ana   Tommie   Albort      Ana   Albert   Albert   Albort 
"Albert"  "Tommy"    "Rob"  "Tommy"    "Rob"  "Tommy"    "Ana"    "Rob"  "Tommy"    "Ana"  "Tommy" "Albert"    "Ana" "Albert" "Albert" "Albert" 
   Tommy    Tommy    Tommy      Ana 
 "Tommy"  "Tommy"  "Tommy"    "Ana" 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM