【问题标题】:Applying a custom function to multiple files and creating unique csv output in R将自定义函数应用于多个文件并在 R 中创建唯一的 csv 输出
【发布时间】:2021-01-22 09:04:38
【问题描述】:

我是 R 的初学者,并且一直在编译代码以创建自定义函数,以对我拥有的某些数据执行特定任务。自定义函数的结构是为了识别 csv 文件中的缺失数据并使用平均值对其进行修补。此后,我想按年和月汇总数据并将其导出为 csv 文件。我有多个 csv 文件位于一个文件夹中,并希望对这些文件中的每一个执行此任务。到目前为止,我能够获得执行手头任务的代码,但不知道如何为每个已处理的 csv 文件编写唯一的输出并将它们保存到新文件夹中。我还想在处理后的输出中保留原始文件名,但要附加“_processed”字样。此外,非常欢迎有关如何改进此代码的任何建议。提前致谢。

# Load all packages required by the script
library(tidyverse) # data science package
library(lubridate) # work with dates
library(dplyr)     # data manipulation (filter, summarize, mutate)
library(ggplot2)   # graphics
library(gridExtra) # tile several plots next to each other
library(scales)

# Set the working directory #
setwd("H:/Shaeden_Post_Doc/Genus_Exchange/GEE_Data/MODIS_Product_Data_Raw/Cold_Temperate_Moist")


#create a function to summarize data by year and month
#patch missing values using the average

summarize_by_month = function(df){
  
# counting unique, missing and mean values in the ET column
df %>% summarise(n = n_distinct(ET),
                   na = sum(is.na(ET)),
                   med = mean(ET, na.rm = TRUE))
  
# assign mean values to the missing data and modify the dataframe
df = df %>%
    mutate(ET = replace(ET,is.na(ET),mean(ET, na.rm = TRUE)))
df
  
#separate data into year, month and day  
df$date = as.Date(df$date,format="%Y/%m/%d")

#summarize by year and month 

df %>%
    mutate(year = format(date, "%Y"), month = format(date, "%m")) %>%
    group_by(year, month) %>%
    summarise(mean_monthly = mean(ET))

}

#import all files and execute custom function for each
file_list = list.files(pattern="AET", full.names=TRUE)
file_list

my_AET_files = lapply(file_list, read_csv)
monthly_AET = lapply(my_AET_files, summarize_by_month)
monthly_AET 

下面提供了示例数据集的链接 https://drive.google.com/drive/folders/1pLHt-vT87lxzW2We-AS1PwVcne3ALP2d?usp=sharing

【问题讨论】:

    标签: r function csv


    【解决方案1】:

    您可以在同一个函数中读取、操作数据和写入 csv:

    library(dplyr)
    
    summarize_by_month = function(file) {
      df <- readr::read_csv(file)
    
      # assign mean values to the missing data and modify the dataframe
      df = df %>% mutate(ET = replace(ET,is.na(ET),mean(ET, na.rm = TRUE)))
    
      #separate data into year, month and day  
      df$date = as.Date(df$date,format="%Y/%m/%d")
    
      #summarize by year and month 
      new_df <- df %>%
        mutate(year = format(date, "%Y"), month = format(date, "%m")) %>%
        group_by(year, month) %>%
        summarise(mean_monthly = mean(ET))
      
         write.csv(new_df, sprintf('output_folder/%s_processed.csv', 
               tools::file_path_sans_ext(basename(file))), row.names = FALSE)
    }
    
    monthly_AET = lapply(file_list, summarize_by_month)
    

    【讨论】:

    • 感谢您的建议,这似乎是对该功能的一个非常简单的补充,并且绝对是我想要使用的东西。我已经指定了将写入 csv 文件的输出文件夹的文件路径(在上面的代码中),然后重新运行代码,但现在收到以下错误“as.character(x) 中的错误:无法强制类型”闭包'到'字符'类型的向量“。什么可能导致此错误?
    • @ShaedenGokool 我通过添加basename 更改了write.csv 中代码的最后一行。你能再次运行它并检查它是否更正吗?
    • @RounakShah。我根据您最近的建议修改了我的代码,见上文。以前的错误不再出现,但现在我收到以下错误“错误:file 必须是字符串、原始向量或连接。”感谢您的帮助。
    • @ShaedenGokool 您需要读取函数内部的数据,而不是外部的lapply。请参阅我将file_list 传递给summarize_by_month 函数的更新答案。
    • @RounakShah。非常感谢它完美地工作。亲切的问候。
    【解决方案2】:
    path<-"your_peferred_path/" #set a path to were you want to save the files
    
    x<-list.files(pattern= "your_pattern") # create a list of your file names
    
    name<-str_sub(x, start=xL, end=yL) #x & y being the part of the name you want to keep 
    
    for (i in 1:length(monthly_AET)){
      write_excel_csv(monthly_AET[i], paste0(path, name, "_processed.csv")) # paste0 allows to create custom names from variables and static strings
    }
    

    注意:这只是一个假设,可能需要根据您的需要进行调整

    【讨论】:

      猜你喜欢
      • 2021-02-20
      • 2020-06-17
      • 2013-06-29
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 2020-12-09
      • 1970-01-01
      • 2017-04-24
      相关资源
      最近更新 更多