James
James

Reputation: 123

Looping through files, NetCDF operations

I am trying to execute the following code for hundreds of NetCDF files, and combine the outcome of this code for each file together.

  library(raster)
  b <- brick('CA.195001.nc')
  be <- crop(b, extent(-177.0170, -117.2690, 32.7191, 32.9753)) 
  a <- aggregate(be, dim(be)[2:1], na.rm=TRUE)
  v <- values(a)

  #get date
  date <- getZ(be)

  df <- data.frame(date=date, prec=t(v)) 
  rownames(df) <- c()
  df


  df$date<- as.Date(df$date, "%m/%d/%Y") #Add dates
  df$year <- as.numeric(format(df$date, format = "%Y"))
  df$month <- as.numeric(format(df$date, format = "%m"))
  df$day <- as.numeric(format(df$date, format = "%d"))

I am fairly new to looping, and haven't found much helpful guidance. The following helps identify the files, but I'm not quite sure how to loop through my above operations:

files <- list.files(path="mypath", pattern="*.nc", full.names=T, 
recursive=FALSE)
lapply(files, function(x) { 
}

Thank you!

Upvotes: 1

Views: 761

Answers (1)

Tung
Tung

Reputation: 28441

You can put your code into a function then use either lapply or purrr:map_df to apply that function over all the NetCDF files

library(raster)

read_ncdf <- function(input_NetCDF_file) {
  b  <- brick(input_NetCDF_file)
  be <- crop(b, extent(-177.0170, -117.2690, 32.7191, 32.9753)) 
  a  <- aggregate(be, dim(be)[2:1], na.rm=TRUE)
  v  <- values(a)

  #get date
  date <- getZ(be)

  df <- data.frame(date=date, prec=t(v)) 
  rownames(df) <- c()

  df$date<- as.Date(df$date, "%m/%d/%Y") #Add dates
  df$year <- as.numeric(format(df$date, format = "%Y"))
  df$month <- as.numeric(format(df$date, format = "%m"))
  df$day <- as.numeric(format(df$date, format = "%d"))

  return(df)
}

List all NetCDF files in mypath

files <- list.files(path = "mypath", pattern = "\\.nc$", full.names = TRUE, 
                recursive = FALSE)

Using lapply

result <- lapply(files, function(x) { read_ncdf(x) })
# rbind all together 
result_df <- do.call("rbind", result) 

Using purrr::map_df

library(tidyverse)
# Loop through all the files using map_df, read data 
# and create a FileName column to store filenames
# Then clean up filename: remove file path and extension
result_purrr <- files %>%
  purrr::set_names(nm = (basename(.) %>% tools::file_path_sans_ext())) %>%
  purrr::map_df(read_ncdf, .id = "FileName") 

Upvotes: 2

Related Questions