【问题标题】:Pattern matching using lapply in R在 R 中使用 lapply 进行模式匹配
【发布时间】:2020-06-12 15:29:07
【问题描述】:

在 R 中,我拥有来自多达 44 个不同地点的降雨数据。包含降雨数据的子文件夹如下所示:

“data_in/1995”、“data_in/1996”、“data_in/2019”

第一个文件夹的前5个文件如下: "S01Y95.out" "S02Y95.out" "S03Y95.out" "S04Y95.out" "S05Y95.out"

我的 R 代码创建了一个子文件夹名称列表,并应用了一个函数来查找带有“S01”的文件,即站点号 1。lapply 函数应用于一个子文件夹名称列表。然后代码将匹配“S01”模式的文件复制到另一个文件夹,以供进一步分析。这一切工作正常,使用以下代码(对不起 - 我还没有弄清楚如何使用 dput 以及你有什么来创建一个漂亮的可重现示例):

# set path to the directory with the raw data
data_in_path<-'data_in'

# get the names of the subfolders
subfolder_names<-dir(data_in_path,full.names = TRUE)
subfolder_names<-as.list(subfolder_names)

S01_raw_path<-'Site_Data/S01_Raw'

# function to search subdirectories for matching files
p_match_Function <- function(files){

  # reference the full path and the input file name using file.path
  file_match<-list.files(files,pattern = "S01")

  # copy the matching file to site subdirectory
  file.copy(file.path(files,file_match), S01_raw_path)
}

# use lapply to run p_match function on each subfolder
lapply(subfolder_names, function(x) p_match_Function(x))

上面的代码有效,但请注意我在函数内部指定了模式匹配(“S01”)。这可行,但这并不理想,因为我宁愿传递站点名称,例如“S01”、“S02”给函数使用一个列表。另一种方法是调用 p_match 函数大约 48 次,每次手动将模式匹配(站点名称)指定为“S01”、“S02”等。

我尝试了如下的 for 循环,但它给了我一个错误。

# strip the site names from the raw file names in the 2019 folder
site_names<-strtrim(dir('data_in/2019'),3)

# loop through the site names and pass the site name to the p_match_function

for (i in seq_along(site_names)) {
  name<-site_names[i]
  lapply(subfolder_names, function(x,name) p_match_Function(x,name))
}  

这会给出错误“p_match_Function(x, name) 中的错误:未使用的参数 (name)”。

我真的被困在这里了。我怀疑我在第二个例子中调用 lapply 的方式是完全错误的。我应该忘记使用 lapply 并返回使用嵌套循环吗?这违反了函数式编程方法,这是使用 R 的真正优势。想法?

[1]

另一个用户回复了一个建议,但我仍然收到错误消息。我在另一篇文章中找到了答案“将几个参数传递给 lapply 的 FUN(以及其他 * apply)。所以最后我只需要修改 lapply 调用如下并解决了问题:

# loop through the site names and pass the site name to the p_match_function

for (i in seq_along(site_names)) {

  name<-site_names[i]
#  lapply(subfolder_names, function(x,name) p_match_Function(x,name))
  lapply(subfolder_names, p_match_Function, name)

}  

【问题讨论】:

    标签: r lapply


    【解决方案1】:

    错误代码告诉您p_match_Function不接受参数名称,这是因为现在它只接受files作为参数。 您应该在参数中包含名称:

    p_match_Function <- function(files,name){
    
      # reference the full path and the input file name using file.path
      file_match<-list.files(files,pattern = name)
    
      # copy the matching file to site subdirectory
      file.copy(file.path(files,file_match), S01_raw_path)
    }
    

    【讨论】:

    • 好的,我理解这个问题,但是当我修改我的代码时,我仍然得到一个错误。这是修改后的代码:
    • 能否将修改后的代码直接分享到问题中?
    • 以下代码抛出错误,因为我的函数调用不正确:
    【解决方案2】:

    好的,这里的代码不起作用,因为函数调用不正确:

    # function to search subdirectories for matching files
    p_match_Function <- function(files,name) {
    
      # find a file that matches pattern = name
      file_match<-list.files(files,pattern = name)
    
      # copy the matching file to site subdirectory
      file.copy(file.path(files,file_match), S01_raw_path)
    }
    #
    # strip the site names from the raw file names in the 1995 folder
    site_names<-strtrim(dir('data_in/1995'),3)
    
    # loop through the site names and pass the site name to the p_match_function
    
    for (i in seq_along(site_names)) {
    
      name<-site_names[i]
      lapply(subfolder_names, function(x,name) p_match_Function(x,name))
    
    }  
    

    另一方面,这里是有效的代码。不仅改变了 lapply 的行:

    # function to search subdirectories for matching files
    p_match_Function <- function(files,name) {
    
      # find a file that matches pattern = name
      file_match<-list.files(files,pattern = name)
    
      # copy the matching file to site subdirectory
      file.copy(file.path(files,file_match), S01_raw_path)
    }
    #
    # strip the site names from the raw file names in the 1995 folder
    site_names<-strtrim(dir('data_in/1995'),3)
    
    # loop through the site names and pass the site name to the p_match_function
    
    for (i in seq_along(site_names)) {
    
      name<-site_names[i]
      lapply(subfolder_names, p_match_Function, name)  
    }  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-27
      • 2013-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多