我应该如何在R中以惯用方式链接lapply序列?

时间:2014-06-13 02:03:02

标签: r

我刚刚编写了一个函数,它使用一系列lapply调用来转换数据,如下所示:

somefun <- function(directory, id = 1:332) {
  filenames <- sprintf("%03d.csv", id)
  filenames <- paste(directory, filenames, sep="/")
  ldf <- lapply(filenames, read.csv)
  cdf <- lapply(ldf,complete.cases)
  icdf <- lapply(cdf,as.numeric)
  sicdf <- lapply(cdf,sum)
  result <- cbind(id,sicdf)
  result
}

有没有更好的方法在R中编写lapplys的这个序列?

2 个答案:

答案 0 :(得分:6)

它并不总是最好的方法,但我最喜欢简化一系列调用的方法是使用magrittr包。

它实际上创建了一个管道,它可以将参数从一个命令转发到另一个命令。对于像这样的长链或一系列调用,它确实很奇怪。句点/点可用于指定前一阶段的值被管道传送的位置。&#39;

尝试这样的事情:

library(magrittr) # use install.packages("magrittr") if needed

sprintf("%03d.csv", id) %>%
    paste(directory, filenames, sep="/") %>%
    lapply(read.csv) %>%
    lapply(complete.cases) %>%
    lapply(as.numeric) %>%
    lapply(sum) %>%
    cbind(id, .)

答案 1 :(得分:0)

您可以使用Reduce策略。这是一些示例数据

xx<-matrix(runif(25), nrow=5)
xx[2,3]<-NA
write.table(xx, "num.txt")

然后你可以运行

trans<-list(
    read.table,
    function(x) x[complete.cases(x),],
    colSums
)

Reduce(lapply, trans, list("num.txt"))

请注意,您提供的某些功能可能无法按照您的意愿运行。例如,complete.cases根本没有真正的子集,你能看到我如何在我的转换列表中使用它。同样适用于as.numericsum