#- ej_001_importar-varios-archivos.R: curso intro R (2024)
#- objetivo: aprender a importar varios archivos a la vez

library(tidyverse)

#- 1) exportar -----------------------------------------------------------------
#- primero vamos a exportar iris 3 veces a la carpeta "./probando/"
fs::dir_create("probando")

#- estructura de un bucle for
for (ii in 1:3) {
  print(ii)
}

#- vamos a usar la f. rio::export() 
#- 0) Vamos a usar la f. rio::export() ; algo como:
# rio::export(iris, here::here("probando", "iris.csv"))

#- 1a) creamos un vector con los nombres de los 3 archivos
my_vec_names <- c("iris_2018.csv", "iris_2019.csv", "iris_2020.csv")

#- 1b) generamos las rutas de los archivos
my_rutas <- paste0("./probando/", my_vec_names)


#- 1c) bucle para guardar

for (ii in 1:3) {
  print(my_rutas[ii])
  rio::export(iris, my_rutas[ii])
}



#- 1d) más escueto con purrr y lapply ( )
purrr::map(my_rutas, .f = \(xx) rio::export(iris, file = xx))

lapply(my_rutas, FUN = \(xx) rio::export(iris, file = xx))



# 2) importar ------------------------------------------------------------------
#- ok, ya tenemos 3 archivos en una carpeta, ahora vamos a importarlos
#- evidentemente, los .csv tienen los mismos nombres para las columnas 


#- 2a) primero vamos a hacerlo con un bucle
rutas_a_files <-  fs::dir_ls("probando")  #-vector con las rutas de todos los archivos en ./probando/
rutas_a_files <-  fs::dir_ls("probando", regexp = "[.]csv$") #-vector con las rutas a los archivos .csv

#- "preparación" del data.frame donde vamos a guardar los datos
mys_datos <- rio::import(rutas_a_files[1]) %>% #- cargo uno de los .csv's
  mutate(id = 1, .before = 1) %>%              #- genero una v. q marque el df de procedencia de los datos
  mutate(year = 2018, .after = id) %>%         #- creo tb v. con el año
  slice(0)                                     #- dejo el data.frame vacio

#- loop para cargar los ficheros y fusionarlos
for (ii in 1:length(rutas_a_files)){
  tmp <- rio::import(rutas_a_files[ii]) %>% 
    mutate(id = ii, .before = 1) %>% 
    mutate(year = 2018 + (ii-1), .after = id)
  mys_datos <- bind_rows(mys_datos, tmp)
}


#- de forma más rápida con purrr
mys_datos.2 <- rutas_a_files %>% purrr::map_df(readr::read_csv, .id = "id")



#- EXTENSIONES.1 -----------------------------------------------------------------
#- no es fácil-fácil
#- vamos a ver como podríamos importar varios archivos de datos en una misma carpeta
#- No es fácil!!
#- Un post: https://kieranhealy.org/blog/archives/2023/03/25/reading-remote-data-files/  
#- aunque usa map_dfr() que en purrr 1.0.0 ha quedado superseded: https://fosstodon.org/@johnmackintosh/109768966119899585

library(tidyverse)

#- Para ello, primero vamos a crear varios conjuntos de datos
#- primero creamos solo un fdf con assign(). Esto no es fácil-fácil
assign(paste0("iris_", "01"), iris)
rm("iris_01")

#- ok, ahora vamos a crear 3 ficheros de datos con la misma estructura
#- esto no es fácil-fácil
anyos <- c(2021:2023)
my_names <- vector()

for (ii in 1:length(anyos)) {
  print(anyos[ii])
  my_names[ii] <- paste0("iris_", anyos[ii])
  assign(my_names[ii], iris)
}

#- OK, tenemos 3 df's q queremos exportar
#- esto no es fácil-fácil
get("iris_2021")

fs::dir_create("./probando/muchos_iris/") #- creo la carpeta

for (ii in 1:length(my_names)) {
  my_name <- my_names[ii]
  my_df <- get(my_name)
  my_ruta <- paste0("./probando/muchos_iris/", my_name, ".csv")
  print(my_ruta)
  rio::export(my_df, my_ruta)
}

rm(my_df)

#- OK, ya tenemos 3 archivos de datos (.csv) q queremos importar
#- AQUI en realidad empezaría el ejercicio de importación de un conjunto de archivos con datos

my_carpeta <- here::here("probando", "muchos_iris") #- la carpeta donde están los archivos q quiero importar

#- cojo las rutas a los archivos
mys_rutas <- list.files(my_carpeta)   #- Ok con base ...
mys_rutas <- fs::dir_ls(my_carpeta)  #- pero mejor con el pkg "fs"
mys_rutas

#- genero nombres para los df's donde se almacenarán los datos de los archivos
mis_nombres <- paste0("iris_imp_", 2021:2023)

for (ii in 1:length(mys_rutas)) {
  assign(mis_nombres[ii], rio::import(mys_rutas[ii]))
}


#- con purrr es easy, PERO hay que saber un poco sobre manipular listas
my_dfs_list <- purrr::map(mys_rutas, rio::import)

#- 2 posibilidades para combinarlas
tbl.0 <- my_dfs_list %>% purrr::reduce(bind_rows)
tbl.0 <- bind_rows(my_dfs_list, .id = "id")


#- MÁS PRO
#- esto sería lo (casí) feten
tbl.1 <- fs::dir_ls("probando/muchos_iris/", regexp = "[.]csv$") %>%
  purrr::map_dfr(readr::read_csv, .id = "id")



#- más intuitivo podría ser algo así:
rutas_a_files <-  fs::dir_ls("probando/muchos_iris/", regexp = "[.]csv$") #-vector con las rutas a los archivos .csv


tbl.2 <- rio::import("./probando/muchos_iris/iris_2021.csv") %>% #- cargo uno de los .csv's
  mutate(id = 1, .before = 1) %>%   #- genero una v. q marque el df de procedencia de los datos
  slice(0)                          #- dejo el data.frame vacio

#- loop para cargar los ficheros y fusionarlos
for (ii in 1:length(rutas_a_files)){
  tmp <- rio::import(rutas_a_files[ii]) %>% mutate(id = ii, .before = 1)
  tbl.2 <- bind_rows(tbl.2, tmp)
}

rm(tmp)

#- EXTENSIONES.2 -----------------------------------------------------------------
#- Nota: la ultima vez q lo corrí no funcionó con rio (abril-2024)
#- prueba xlsx::write.xlsx
#- vamos a ver como podríamos importar libros de un archivo Excel
#- No es fácil!!
#- Un post: https://kieranhealy.org/blog/archives/2023/03/25/reading-remote-data-files/  aunque uso map_dfr() que en purrr 1.0.0 ha quedado superseded: https://fosstodon.org/@johnmackintosh/109768966119899585
#- otro post de exportar several df's to an excel file: https://cran.r-project.org/web/packages/tablexlsx/vignettes/aa-examples.html#export-a-list-of-several-data-frames-to-an-xlsx-file-several-data-frames-in-a-same-sheet

library(tidyverse)

#- Para ello, primero vamos a crear varios conjuntos de datos
#- primero creamos solo un fdf con assign(). Esto no es fácil-fácil
assign(paste0("iris_", "01"), iris)
rm("iris_01")

#- ok, ahora vamos a crear 3 ficheros de datos con la misma estructura
#- esto no es fácil-fácil
anyos <- c(2021:2023)
my_names <- vector()

for (ii in 1:length(anyos)) {
  print(anyos[ii])
  my_names[ii] <- paste0("iris_", anyos[ii])
  assign(my_names[ii], iris)
}

#- OK, tenemos 3 df's q queremos exportar a un archivo .xlsx
#- esto no es fácil-fácil
get("iris_2021")

fs::dir_create("./probando") #- creo la carpeta

#- pedro.j.perez@uv.es [revisado: 2024-09-04]
#- ejemplo sobre exportacion-importación datos en R

#- exportamos el primer df aun .xlsx (ya no con rio)

xlsx::write.xlsx(iris,  file = here::here("probando", "iris.xlsx"), sheetName = "iris_2021", append = TRUE)


#- ahora el resto de df's en libros del mismo archivo .xlsx
for (ii in 2:length(my_names)) {
  my_name <- my_names[ii]
  my_df <- get(my_name)
  #rio::export(my_df, my_ruta)
  xlsx::write.xlsx(x = my_df,
              file = here::here("probando", "iris.xlsx"),
              sheetName = my_name,
              append = TRUE)
}

rm(my_df)


#- OK, ya tenemos 1 archivo Excel con 3 libros q queremos importar
#- AQUI en realidad empezaría el ejercicio de importación

my_archivo <- here::here("probando", "iris.xlsx") #- ruta al archivo

library(readxl)
my_dfs_list.1 <- lapply(excel_sheets(my_archivo),
                        read_excel,
                        path = my_archivo)

my_dfs_list.2 <- purrr::map(excel_sheets(my_archivo),
                            read_excel,
                            path = my_archivo)



#- tanto con purrr() como con lapply() es easy, PERO hay que saber un poco sobre manipular listas
#- 2 posibilidades para combinarlas
tbl.0 <- my_dfs_list.2 %>% purrr::reduce(bind_rows)
tbl.0 <- bind_rows(my_dfs_list.2, .id = "id")




#- EXTENSIONES.3 ---------------------------------------------------------------
# https://github.com/vsbuffalo/devnotes/wiki/Data-Analysis-Patterns
#- vamos a cargar en R todos los ficheros de un directorio
#- para ello primero grabamso iris en varios ficheros

### example setup:
library(tidyverse)
library(purrr)

DIR <- './datos/ejemplos/pruebas/pruebas_ej_18' # vamos acrear en este directorio un grupo de ficheros de datos
dir.create(DIR) #- creamos ese directorio

# filenames to make example work:
files <- c('sampleA_rep01.tsv', 'sampleA_rep02.tsv','sampleB_rep01.tsv', 
           'sampleB_rep02.tsv', 'sampleC_rep01.tsv', 'sampleC_rep02.tsv') #- crearemos 6 ficheros de datos

#- para ello primero grabamos iris en varios ficheros
#- file.path() construye las rutas y se aplica con purrr:walk a el conjunto de names en files
walk(files, ~ write_tsv(iris, file.path(DIR, .)))    #- walk es similar to map but calls .f for its side-effect and returns the input .x. walk() returns the input .x (invisibly). This makes it easy to use in pipe.

# Una vez tenemos DIR con 6 ficheros de datos, vamos a trerlos a R todos de golpe:
input_files <- list.files(DIR, pattern = 'sample.*\\.tsv', full.names = TRUE)   #- "sample.*\\.tsv" es uan expression regular

#- Ok, en input_files tenemos la ruta a los 6 ficheros sample....tsv
# data loading pattern:
all_data <- tibble(file = input_files) %>%                  #- crea una tible con las rutas a los ficheros
  mutate(data = map(file, read_tsv)) %>%          #- crea un acolumna con los datos de cada fichero
  mutate(basename = basename(file)) %>%           #- crea una columna con el nombre del fichero  
  tidyr::extract(basename, into = c('sample', 'rep'), regex = 'sample([^_]+)_rep([^_]+)\\.tsv')  #- parte la columna cread antes (basename) en 2 columnas: "sample" y "rep"

#- OK tenemos almacenados los datos de los 6 ficheros en las seis rows de la columna "data"
#- ahora depende de lo queramos haremos una cosa u otra: p.ej:
aa <- all_data[[2]] %>% `[[`(.,1)         #- cogemos los datos del primer fichero
aa <- all_data[["data"]] %>% `[[`(.,4)    #- cogemos los datos del cuarto fichero

aa <- all_data %>% select(2) %>% slice(5) %>% unnest    #- cogemos los datos del quinto fichero
aa <- all_data %>% select(data) %>% slice(3) %>% unnest #- cogemos los datos del tercer fichero

bb <-  all_data %>% unnest(data)  # - AQUI: pones los datos de los seis ficheros TODOS juntos


#- borro el directorio q hemos usado
unlink(DIR, recursive = TRUE)
