代码之家  ›  专栏  ›  技术社区  ›  mropa

编码R-Light Way-避免for循环

  •  4
  • mropa  · 技术社区  · 15 年前

    我正在浏览我的一个.r文件,通过清理它一点点,我试图更加熟悉以正确的方式编写代码。作为一个初学者,我最喜欢的出发点之一是摆脱 for() 循环并尝试将表达式转换为函数式编程形式。 下面是场景:

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

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

    现在,我想看看每个数据。框架的列名,并替换某些字符串。我喜欢用“baz”代替每个“foo”和“bar”。目前我正在用一个 () 循环,看起来有点笨拙。

    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")
      }
    }
    

    因为我在这里工作 列表 我想到了 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)
    

    我看到没有对初始字符串进行任何更改。

    那么我如何重写 () 循环并将其转换为函数式编程形式? 如何有效地替换字符串“foo”和“bar”?自从 gsub() 函数作为其 pattern 参数只有长度为1的字符向量。

    1 回复  |  直到 15 年前
        1
  •  9
  •   Leo Alekseyev    15 年前

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

    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中的regex中使用备用模式(“foo_bar”)。

    注意,顺便说一下,您不必通过索引到列表中来完成这项工作——只需使用一个直接对列表元素进行操作的函数:

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