gpt4 book ai didi

r - 如何将循环结构更改为 sapply 函数?

转载 作者:行者123 更新时间:2023-12-04 09:31:53 26 4
gpt4 key购买 nike

我已经将 for 循环更改为 sapply 函数,但是失败了。
我想知道为什么?

list.files("c:/",pattern="mp3$",recursive=TRUE,full.names=TRUE)->z    
c()->w
left<-basename(z)
for (i in 1:length(z)){
if (is.element(basename(z[i]),left))
{
append(w,values=z[i])->w;
setdiff(left,basename(z[i]))->left
}}
print(w)



list.files("c:/",pattern="mp3$",recursive=TRUE,full.names=TRUE)->z
c()->w
left<-basename(z)
sapply(z,function(y){
if (is.element(basename(y),left))
{ append(w,values=y)->w;
setdiff(left,basename(y))->left
}})
print(w)

我选择音乐的规则是,如果basename(music)相同,则只保存一个full.name of music,所以不能直接使用unique。有两个概念full文件路径中的 .name 和 basename 可能会使此处的人感到困惑。

最佳答案

这里的问题是您希望您的函数有两个副作用。副作用,我的意思是修改超出其范围的对象:wleft .

目前,wleft仅在函数范围内修改,然后它们最终会在函数调用结束时丢失。

相反,您想修改 wleft在函数的环境之外。为此,您可以使用 <<-而不是 <- :

sapply(z, function(y) {    
if (is.element(basename(y),left)) {
w <<- append(w, values = y)
left <<- setdiff(left, basename(y))
}
})

请注意,我一直在说“你想要”、“你可以”,但这不是“你应该”做的。具有副作用的函数确实被认为是糟糕的编程。尝试阅读它。

此外,最好保留 *apply工具到可以独立运行其输入的功能。相反,您有一个算法,其中迭代的结果取决于先前迭代的结果。在这些情况下,您最好使用 for循环,除非您可以在更适合 *apply 的框架中重新考虑该算法或者可以使用可以处理这种依赖情况的函数:filter , unique , rle

例如,使用 unique ,您的代码可以重写为:

base.names <- basename(z)
left <- unique(base.names)
w <- z[match(left, base.names)]

它的另一个优点是它不会递归地构建对象,这是您当前代码的另一个禁忌。

关于r - 如何将循环结构更改为 sapply 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20241255/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com