řsapply环以取代环(R sapply loop to replace for loop)

2019-09-29 23:07发布

我已成功切换为循环之前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层的元件。 我的()溶液返回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:谢谢你,现在我已经是sapply霸主 ,我在这里只是为了显示我的其他换sapply与adist使用替代()

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]

另一部分你已经重新认识,谢谢!

Answer 1:

采用该解决方案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" 


Answer 2:

如果有之间的一个-一一对应misspell.listfix.list您可以通过使用破除环路match功能

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

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


Answer 3:

我想提出一个小的改变你的整个设置。 当使用索引像你这样做,你需要确保秩序始终是相同的。 如果您添加或删除名称,整个事情分崩离析。

使用命名列表和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矢量并将其扩展到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" 


文章来源: R sapply loop to replace for loop