1

我在 R 编程的第一周,虽然我在解决特定问题方面取得了很大进展,但我需要更大规模的建议。

我有一个充满 CSV 格式数据文件的目录。文件名专门标识数据源。我需要导入数据,通过各种计算条件化数据,并保留每个文件的条件化结果以供分析和查看。我已经成功地学会了在单个文件的基础上打开和广泛地调整数据。调节导致多重计算输出。我需要自动化这个过程并根据各自的文件名动态命名结果。

由于每个文件的数据条件都是相同的,因此我编写了一个可以为每个文件调用的函数。我了解函数在它们自己的环境中运行,该环境在函数运行后消失。我可以使用粘贴动态命名变量来构建名称并分配以将结果分配给这些名称。当函数关闭时,这些分配将丢失。

我不确定单步执行所有文件并将所有单独的计算结果保留在工作区中的最佳方式。我知道我“应该”将函数输出写入一个列表,稍后我可以对其进行索引。但是,我会有数百个计算结果,以后的索引会很复杂。假设其中两个文件包含不同位置的气温测量值。由于我根据描述性文件名动态命名计算结果,因此我可以将结果存储为 Temperature.Air.Location1 和 Temperature.Air.Location2。我更喜欢稍后通过简单地键入 Temperature.Air.Location1 - Temperature.Air.Location2 来计算温度增量的能力,而不必查找大列表的相应索引。

我确信有一种优雅的方式来实现这一点,这让我眼前一亮,但我担心我已经完全沉浸在学习 R 中的函数、插值和绘图中,以至于我忘记了大图。非常感谢任何建议。

编辑以添加示例代码 在函数的这一部分中,我将表格转换为 x、y、z 坐标以及对值进行插值。

CalibrationImport.Table <- function(filename, parametername, xmin, xmax, ymin, ymax){
  Path.File <- paste0(Path.Folder,filename)
  assign(parametername, read.csv(Path.File, header = FALSE))

  # Extract x coordinates from original table
  assign(paste0(parametername,".x"), get(parametername)[1, ])
  assign(paste0(parametername,".x"), unlist(get(paste0(parametername,".x"))[-1], use.names=FALSE))
  assign(paste0(parametername,".x"), c(t(replicate(nrow(get(parametername))-1, get(paste0(parametername,".x"))))))

  # Extract y coordinates from original table
  assign(paste0(parametername,".y"), get(parametername)[ ,1])
  assign(paste0(parametername,".y"), unlist(get(paste0(parametername,".y"))[-1], use.names=FALSE))
  assign(paste0(parametername,".y"), c(replicate(ncol(get(parametername))-1, get(paste0(parametername,".y")))))

  # Extract data for original table
  assign(paste0(parametername,".z"), unlist(get(parametername)[-1, -1], use.names=FALSE))

  # Interpolate 100x100 surface
  assign(paste0(parametername,".i"), interp(get(paste0(parametername,".x")), get(paste0(parametername,".y")), get(paste0(parametername,".z")),
                                        xo=seq(xmin, xmax, length=100), yo=seq(ymin, ymax, length=100)))
}
4

2 回答 2

4

不要在函数assign 内部使用,在函数的结果外部使用它assign,即

 `assign( "name1" , myfunc(x) )`

如果你将它应用到你的 CSV 文件目录,你可以做类似这样的事情:

fl <- list.files( "path/to/my/directory" , pattern = ".csv" )

for( i in 1: length(fl) ){      
  assign( paste0( "file." , i ) , myfunc( fl[i] ) )
}

这是for循环的经典用途之一——应用它来解决它的副作用。

但是,您有数百个文件,因此lapply可能会更好,它将以列表的形式返回结果,并且在语法上非常简单:

myresults <- lapply( fl , myfunc )

但是,您可能需要重写部分函数,​​使其不分配任何内容,而是返回您想要保留的值。使用赋值(即<-)将返回值放入工作区中的对象中。如果没有可重现的例子,这只能是一个粗略的草图。

如果您想保留文件的名称,sapply可能会更好,它将您的结果作为向量返回并可以保留名称:

sapply( fl , myfunc , USE.NAMES = TRUE )
于 2013-05-03T11:07:15.973 回答
4

一般来说,适合我的工作流程是使用lapply. 例如:

file_names = list.files(pattern = "*csv")
data_list = lapply(file_names, read.csv)

perform_interpolation = function(dataset) {
   # Perform interpolation on dataset
   return(interpolated_dataset)
}
interpolated_data_list = lapply(data_list, perform_interpolation)

在这里,我有使用函数(即函数式编程)转换的对象列表。关键是要有简单的函数,接受一些输入,然后生成一个输出对象。

没有您提供的更多细节,很难提供更详细的建议。

于 2013-05-03T11:14:06.197 回答