如何动态地将过滤后的data.frame导出到所需的文件夹中?

时间:2016-11-12 14:14:39

标签: r csv dataframe

我已经阅读了文件夹中的csv文件列表,现在我打算将它们过滤掉给定的阈值,其中每个data.frame中的删除行必须以动态方式导出到所需的文件夹,而保存的行作为输出返回。但是,我实现了执行此任务的功能,除了将删除的行写为csv文件到所需的文件夹失败之外,它工作正常。任何人都可以指出我的功能是什么吗?是否可以动态地在特定文件夹中写入data.frame?我该如何纠正实施?有什么想法吗?

可重现的数据:

myData <- list(
  df_1 = data.frame( L1=seq(3, by=4, len=16), L2=seq(7, by=4, len=16), score=sample(30, 16)),
  df_2 = data.frame( L1=seq(6, by=7, len=20), L2=seq(14, by=7, len=20), score=sample(30, 20)),
  df_3 = data.frame( L1=seq(11, by=8, len=25), L2=seq(19, by=8, len=25), score=sample(30, 25))
  )

我实现了这个功能,除了不需要编写csv文件外,它工作正常:

func <- function(mlist, threshold=NULL, outDir=getwd(), .fileName=NULL, ...) {
  if(!dir.exists(outDir)) {
    dir.create(file.path(outDir))
    setwd(file.path(outDir))
  }
  rslt <- lapply(mlist, function(x) {
    .drop <- x[x$score < threshold,]
    # FIXME : write droped rows of each data.frame into specific folder
    write.csv(.drop, sprintf("drop.%s.csv", x), row.names = FALSE)
    .save <- x[x$score >= threshold,]
    return(.save)
  })
  return(rslt)
}

这是我打算在特定位置编写csv文件:与.initPath .initPath = getwd()连接,创建新文件夹并在那里编写csv文件。我不明白我的实施出了什么问题,我收到了一个错误。

如何动态地将每个data.frame中的已删除行写入特定文件夹?有没有快速的方法可以更有效地实现这一目标?非常感谢。

1 个答案:

答案 0 :(得分:3)

目前,在write.csv()行中,您将数据框对象xsprintf()连接到文件名中。您需要将dataframe对象的名称连接到文件名。

因此,请考虑将lapply()替换为Map()函数(并Map作为mapply(func, x, y, SIMPLIFY=FALSE)的包装,其中为mlist本身传递两个参数, mlist名称。请注意:您可能认为在原始设置中使用names(x)会起作用,但这会返回相应数据框的列名,这些名称在连接到文件名字符串时仍会失败。

func <- function(mlist, threshold=NULL, outDir=getwd(), .fileName=NULL, ...) {
  if(!dir.exists(outDir)) {
    dir.create(file.path(outDir))
    setwd(file.path(outDir))
  }
  rslt <- Map(function(x, y) {
    .drop <- x[x$score < threshold,]

    write.csv(.drop, sprintf("drop.%s.csv", y), row.names = FALSE)
    .save <- x[x$score >= threshold,]
    return(.save)
  }, mlist, names(mlist))
  return(rslt)
}

# EXAMPLE
newData <- func(myData, threshold=10)

如果您确实要保留lapply(),请创建临时变量以捕获df对象和df名称。下面还显示了如何通过将这些值传递给args并将所有值与sprintf()连接来允许动态路径和文件名更改:

func <- function(mlist, threshold=NULL, csvName="", outDir=getwd(), .fileName=NULL, ...) {
  if(!dir.exists(outDir)) {
    dir.create(file.path(outDir))
    setwd(file.path(outDir))
  }
  rslt <- lapply(seq_along(mlist), function(x) {
    df <- mlist[[x]]; dfname <- names(mlist)[x]
    .drop <- df[df$score < threshold,]

    write.csv(.drop, sprintf("%s/%s.%s.csv", outDir, csvName, dfname), row.names = FALSE)
    .save <- df[df$score >= threshold,]
    return(.save)
  })
  return(rslt)
}

# EXAMPLE
newData <- func(myData, threshold=10, csvName=usercsv, outDir=userpath)