【问题标题】:applying same function on multiple files in R在R中的多个文件上应用相同的功能
【发布时间】:2015-06-11 19:48:24
【问题描述】:

我是 R 程序的新手,目前正在处理一组财务数据。现在我的工作目录下有大约 10 个 csv 文件,我想分析其中一个并将相同的命令应用于其余的 csv 文件。

以下是这些文件的所有名称:("US%10y.csv"、"UK%10y.csv"、"GER%10y.csv"、"JAP%10y.csv"、"CHI%10y. csv"、"SWI%10y.csv"、"SOA%10y.csv"、"BRA%10y.csv"、"CAN%10y.csv"、"AUS%10y.csv")

例如,因为 CSV 文件中的 Date 列是 Factor,所以我需要将它们更改为 Date 格式:

CAN <- read.csv("CAN%10y.csv", header = T, sep = ",")
CAN$Date <- as.character(CAN$Date)
CAN$Date <- as.Date(CAN$Date, format ="%m/%d/%y")
CAN_merge <- merge(all.dates.frame, CAN, all = T)
CAN_merge$Bid.Yield.To.Maturity <- NULL

all.dates.frame 是一个连续 731 天的数据框。我想合并它们,以便每个文件具有相同的行数,这使我能够将 10 个文件组合在一起以获得 731 X 11 的主数据框。

当然,我可以复制并粘贴此代码并更改文件名,但有没有简单的方法可以使用 apply 或 for 循环来做到这一点???

非常感谢您的帮助。

【问题讨论】:

    标签: r apply


    【解决方案1】:

    这应该可以解决问题。如果某个部分不起作用,请发表评论。没有测试就写了这个盲注。

    获取当前目录中以.csv结尾的文件列表

    L = list.files(".", ".csv")
    

    遍历每个名​​称并读取每个文件,执行您想要执行的操作,返回 data.frame DF_Merge 并将它们存储在列表中。

    O = lapply(L, function(x) {
               DF <- read.csv(x, header = T, sep = ",")
               DF$Date <- as.character(CAN$Date)
               DF$Date <- as.Date(CAN$Date, format ="%m/%d/%y")
               DF_Merge <- merge(all.dates.frame, CAN, all = T)
               DF_Merge$Bid.Yield.To.Maturity <- NULL
               return(DF_Merge)})
    

    将所有DF_Mergedata.frames绑定到一个大data.frame

    do.call(rbind, O)
    

    我猜你需要某种指标,所以这可能很有用。根据文件名rep(substring(L, 1, 3), each = 731)的前3个字符创建指示符列

    【讨论】:

    • 非常感谢!我认为它有效!还有一个问题,对于 do.call(),如果我想按列 ="Date" 绑定 O 列表,我该怎么做?因为现在,do.call(cbind, O) 只会返回一个包含多个日期列的表。
    • date 列应该堆叠在一起。通过快速谷歌搜索,听起来其他人也有这个问题。听起来像一个错误或什么的。尝试跳过as.Date 步骤并将date 保留为class(character)。一旦绑定O,然后在整个列上执行as.Date。如果这不起作用,请尝试 as.posixct 而不是 as.Date
    【解决方案2】:

    dplyr 解决方案(尽管由于没有给出可重现的示例而未经测试):

    library(dplyr)
    
    file_list <- c("US%10y.csv", "UK%10y.csv", "GER%10y.csv","JAP%10y.csv", "CHI%10y.csv", "SWI%10y.csv","SOA%10y.csv", "BRA%10y.csv", "CAN%10y.csv", "AUS%10y.csv")
    
    can_l <- lapply(
      file_list
      , read.csv
    )
    
    can_l <- lapply(
      can_l
      , function(df) {
        df %>% mutate(Date = as.Date(as.character(Date), format ="%m/%d/%y"))
      }
    )
    
    # Rows do need to match when column-binding
    can_merge <- left_join(
      all.dates.frame
      , bind_cols(can_l)
    )
    
    can_merge <- can_merge %>% 
      select(-Bid.Yield.To.Maturity)
    

    【讨论】:

    • 非常简单的方法!感谢分享!
    【解决方案3】:

    一种可能的解决方案是将所有文件以列表的形式读入 R,然后使用lapply 将函数应用于所有数据文件。例如:

    # Create vector of file names in working direcotry
    files <- list.files() 
    files <- files[grep("csv", files)]  
    
    #create empty list
    lst <- vector("list", length(files))
    
    #Read files in to list
    for(i in 1:length(files)) {
        lst[[i]] <- read.csv(files[i])
    }
    
    #Apply a function to the list
    l <- lapply(lst, function(x) {
        x$Date <- as.Date(as.character(x$Date), format = "%m/%d/%y")
    return(x)
    }) 
    

    希望对你有帮助。

    【讨论】:

    • 谢谢丹尼尔~!我已经尝试了您的解决方案,并且在 lapply 位之前效果很好。 R studio 说:x$Date 中的错误:$ 运算符对原子向量无效。你知道为什么吗?
    • 嗯.. 好吧,回想起来,我注意到我忘记用as.character 包裹x$Date(我已经对其进行了编辑以解决该问题),但看起来不像那样会给你那个错误。如果您在lst 上运行str,您会以列表的形式看到您的数据吗?您可以尝试的一件事是根据其位置对其进行索引(例如,如果 Date 是第二列,则将 x$Date 替换为 x[ ,2])。如果那时它仍然无法正常工作,那么我不确定发生了什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-27
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    • 2021-12-11
    • 2014-05-29
    • 1970-01-01
    相关资源
    最近更新 更多