如何在R中循环批量转换文件夹内所有.sav文件为扁平文件?
Since you already have a working single-file conversion script, scaling it to handle 50+ files is totally doable with a couple of reliable, robust approaches. Below are two practical methods—one using base R, another using the tidyverse—both with built-in error handling to ensure the process doesn't break if a single file has issues.
First, make sure you have the required packages installed (if you haven't already):
install.packages(c("haven", "readr", "purrr")) # purrr is optional for the second method
Method 1: Base R For Loop (Beginner-Friendly)
This approach uses core R functions, so it's easy to follow and modify if you're more comfortable with base syntax.
library(haven) library(readr) # Replace with your actual folder path containing .sav files folder_path <- "path/to/your/sav_files" # Get full paths to all .sav files (ignore case with ignore.case=TRUE if needed) sav_files <- list.files( path = folder_path, pattern = "\\.sav$", full.names = TRUE, ignore.case = TRUE # Uncomment if you have .SAV files too ) # Loop through each file and convert for (file in sav_files) { tryCatch({ # Read the .sav file data <- read_sav(file) # Generate output filename (swap .sav for .csv; change to .txt/.tsv if needed) output_file <- gsub("\\.sav$", ".csv", file, ignore.case = TRUE) # Write to flat file (use write_tsv for tab-separated, or write.table for more control) write_csv(data, output_file) # Print progress update cat("Successfully converted:", basename(file), "\n") }, error = function(e) { # Catch and report errors without stopping the entire loop cat("FAILED to convert:", basename(file), "| Error:", e$message, "\n") }) }
Method 2: Tidyverse purrr::walk (Clean, Functional Style)
If you prefer the tidyverse workflow, this uses purrr::walk (designed for functions that produce side effects like writing files) to keep the code concise.
library(haven) library(readr) library(purrr) folder_path <- "path/to/your/sav_files" sav_files <- list.files(path = folder_path, pattern = "\\.sav$", full.names = TRUE) # Define a reusable conversion function convert_sav <- function(file) { tryCatch({ data <- read_sav(file) output_file <- gsub("\\.sav$", ".csv", file) write_csv(data, output_file) cat("Done:", basename(file), "\n") }, error = function(e) { cat("Error with:", basename(file), "-", e$message, "\n") }) } # Run the conversion on all files walk(sav_files, convert_sav)
Additional Tips for Edge Cases
- Recursive search: If you have .sav files in subfolders, add
recursive = TRUEtolist_files(). - Custom output folder: To save converted files to a separate directory (instead of the original folder), modify the output path:
output_dir <- "path/to/your/output_folder" dir.create(output_dir, recursive = TRUE, showWarnings = FALSE) # Create folder if missing output_file <- file.path(output_dir, gsub("\\.sav$", ".csv", basename(file))) - Encoding fixes: If your .sav files have special characters, specify the encoding when reading/writing:
data <- read_sav(file, encoding = "UTF-8") write_csv(data, output_file, locale = locale(encoding = "UTF-8")) - Change flat format: Swap
write_csvforwrite_tsv(tab-separated) orwrite.table(data, output_file, sep = "|", row.names = FALSE)for custom delimiters.
内容的提问来源于stack exchange,提问作者vap0991

