gpt4 book ai didi

r - 正确的编码方式——避免 for 循环

转载 作者:行者123 更新时间:2023-12-03 07:47:41 25 4
gpt4 key购买 nike

我正在检查我的一个 .R 文件,并通过稍微清理它,我试图更熟悉如何以正确的方式编写代码。作为初学者,我最喜欢的起点之一是摆脱 for() 循环并尝试将表达式转换为函数式编程形式。所以这是场景:

我正在将一堆data.frames组装成一个list以供以后使用。

dataList <- list (dataA,
dataB,
dataC,
dataD,
dataE
)

现在我想查看每个 data.frame 的列名称并替换某些字符串。例如,我喜欢用“baz”代替“foo”和“bar”。目前,我正在使用 for() 循环来完成工作,这看起来有点尴尬。

colnames(dataList[[1]])
[1] "foo" "code" "lp15" "bar" "lh15"
colnames(dataList[[2]])
[1] "a" "code" "lp50" "ls50" "foo"

matchVec <- c("foo", "bar")
for (i in seq(dataList)) {
for (j in seq(matchVec)) {
colnames (dataList[[i]])[grep(pattern=matchVec[j], x=colnames (dataList[[i]]))] <- c("baz")
}
}

由于我在这里使用 list,所以我想到了 lapply 函数。我尝试使用 lapply 函数处理这项工作,看起来一切都不错,但只是乍一看。如果我写

f <- function(i, xList) {
gsub(pattern=c("foo"), replacement=c("baz"), x=colnames(xList[[i]]))
}
lapply(seq(dataList), f, xList=dataList)

最后一行几乎打印出我正在寻找的内容。但是,如果我再看一下 dataList 中 data.frames 的实际名称:

lapply (dataList, colnames)

我发现初始字符串没有发生任何变化。

那么如何重写for()循环并将其转换为函数式编程形式呢?如何以有效的方式替换两个字符串“foo”和“bar”?由于 gsub() 函数仅将长度为 1 的字符向量作为其 pattern 参数。

最佳答案

您的代码几乎可以工作 - 但请记住,R 创建您修改的对象的副本(即按值传递语义)。因此,您需要显式地将新字符串分配给 colnames,如下所示:

dataA <- dataB <- data.frame(matrix(1:20,ncol=5))
names(dataA) <- c("foo","code","lp15","bar","lh15")
names(dataB) <- c("a","code","lp50","ls50","foo")
dataList <- list(dataA, dataB)
f <- function(i, xList) {
colnames(xList[[i]]) <- gsub(pattern=c("foo|bar"), replacement=c("baz"), x=colnames(xList[[i]]))
xList[[i]]
}
dataList <- lapply(seq(dataList), f, xList=dataList)

新列表将包含带有替换名称的数据框。在替换 foo 和 bar 方面,只需在 gsub 的正则表达式中使用替代模式(“foo|bar”)。

顺便说一句,请注意,您不必通过索引列表来完成此操作 - 只需使用直接对列表元素进行操作的函数即可:

f <- function(df) {
colnames(df) <- gsub(pattern=c("foo|bar"), replacement=c("baz"), x=colnames(df))
df
}
dataList <- lapply(dataList, f)

关于r - 正确的编码方式——避免 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2441562/

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