Повторный импорт файлов Excel и усреднение соответствующих значений по имени файла в R - PullRequest
1 голос
/ 30 января 2020

У меня есть папка, содержащая 630 файлов Excel, все с похожими именами файлов. Каждый файл представляет климатические данные в определенных c географических c районах за месяц определенного c года. Моя цель - найти способ повторить мой импорт этих файлов и найти среднее значение для указанных переменных c. Все файлы имеют такие названия:

PRISM_ppt_stable_4kmM3_201201_bil

, где «ppt» представляет собой климатическую переменную, в которой находятся данные, «2012» представляет 2012 год, а «01» представляет январь. Следующий файл в папке называется:

PRISM_ppt_stable_4kmM3_201202_bil

, где «ppt» представляет ту же переменную, «2012» снова представляет 2012 год, а «02» на этот раз представляет февраль месяц , Они повторяются для каждого месяца каждого года и для 7 различных переменных. Переменные озаглавлены:

ppt, vpdmax, vpdmin, tmax, tmin, tdmean, tmean

Каждый файл Excel содержит> 1500 наблюдений 11 переменных, где мне интересно найти среднюю переменную MEAN среди всех соответствующих переменных tl_2016_us. Ниже приведены некоторые быстрые выборочные данные:

tl_2016_us MEAN
14136      135.808
14158      132.435
etc.       etc.

Сложно понять, что я могу получить только 10 * 10, чтобы найти свои средние значения за определенный зимний период, в данном случае с ноября по март. Таким образом, все файлы с 201211, 201212, 201301, 201302 и 201303 в имени файла должны соответствовать tl_2016_us, и соответствующие переменные MEAN усредняются. В идеале этот процесс должен повторяться до следующего года 201311, 201312, 201401, 201402, 201403. До этого момента я использовал

list.files(path = "filepath", pattern ="*ppt*")

для создания списков имен моих файлов для каждой из 7 переменных.

Ответы [ 2 ]

1 голос
/ 30 января 2020

Я не совсем понимаю, что означают / означают переменные "tl_2016_us".

Однако вы можете легко получить список только зимних месяцев, используя немного регулярных выражений, например, так:

library(tidyverse) 

# Assuming your files are already in your working directory
all_files <- list.files(full.names = TRUE, pattern = "*ppt*")
winter_mos <- str_subset(files, "[01, 02, 03, 11, 12]_\\w{3}$")

После этого вы можете повторять чтение всех файлов во фрейме данных. с map() из purrr:


library(readxl)

data <- map(winter_mos, ~ read_xlsx(.x)) %>% bind_rows(.id = "id")

После этого вы сможете выбрать нужные переменные, используйте group_by() для группировки по id (т. е. id каждого файла Excel) а затем summarize_all(mean)

0 голосов
/ 30 января 2020

Может быть что-то вроде (не очень элегантно):

filetypes = c("ppt", "vpdmax", "vpdmin", "tmax", "tmin", "tdmean", "tmean")
data_years = c(2012,2013,2014)

df <- NULL

for (i in 1:length(data_years)) {
  yr <- data_years[i]
  datecodes <- c(paste(yr,"11",sep=""), 
                 paste(yr,"12",sep=""),                 
                 paste(yr+1,"01",sep=""),
                 paste(yr+1,"02",sep=""),
                 paste(yr+1,"03",sep=""))
  for (j in 1:length(filetypes)) {
     filetype <- filetypes[j]
     file_prefix <- paste("PRISM",filetype,"stable_4kmM3",sep="_")

     for (k in 1:length(datecodes)) {           
        datecode <- datecodes[k]
        filename <- paste(file_prefix,datecode,"bil",sep="_")
        dk <- read_excel(filename)
        M <- dim(dk)[1]
        dk$RefYr <- rep(yr,M)
        dk$DataType <- rep(filetype,M)
        if (is.null(df_new)) {
          df <- dk
        } else {
          df <- rbind(df,dk) 
        }
     }
  }
}

Как только он будет выполнен, у вас будет фрейм данных, содержащий все данные, необходимые для вычисления ваших средних (я думаю).

Затем вы могли бы сделать что-то вроде:

df_new <- NULL

for (i in 1:length(data_years)) {
  yr <- data_years[i]
  di <- df[df$RefYr==yr,]
  for (j in 1:length(filetypes)) {
     filetype <- filetypes[j]
     dj <- di[di$DataType==filetype,]
     tls <- unique(dj$tl_2016_us)
     for (k in 1:length(tls)) {
       tl <- tls[k] 
       dk <- dj[dj$tl_2016_us==tl,]
       dijk <- data.frame(RefYr=yr,TL2016=tl,DataType=filetype,
                          SeasonAverage=mean(dk$MEAN))
       if (is.null(df)){
         df_new <- dijk
       } else {
         df_new <- rbind(df_new,dijk) 
       }
     }
  }
}

Я уверен, что есть более изящные способы сделать это и что есть некоторые ошибки в приведенном выше, так как я не мог действительно запустить код, но я думаю, что вы должны оставить фрейм данных, содержащий то, что вы ищете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...