J'essaie d'écrire une fonction dans R qui est appelée avec la fonction pmap et renomme les dataframes imbriquées (ou tibbles) qu'elle crée en utilisant un argument passé d'une liste à pmap fonction. Je pense que cela est mieux expliqué avec un exemple de jouet reproductible. En voici un (qui suppose que l'utilisateur s'exécute dans Windows et a le répertoire C: \ temp \ déjà créé et actuellement vide, bien que vous puissiez définir les chemins ci-dessous vers n'importe quel répertoire de votre choix:

#create some toy sample input data files
write.csv(x=data.frame(var1=c(42,43),var2=c(43,45)), file="C:\\temp\\AL.csv")
write.csv(x=data.frame(var1=c(22,43),var2=c(43,45)), file="C:\\temp\\AK.csv")
write.csv(x=data.frame(var1=c(90,98),var2=c(97,96)), file="C:\\temp\\AZ.csv")
write.csv(x=data.frame(var1=c(43,55),var2=c(85,43)), file="C:\\temp\\PossiblyUnknownName.csv")

#Get list of files in c:\temp directory - assumes only files to be read in exist there
pathnames<-list.files(path = "C:\\temp\\", full.names=TRUE)
ListIdNumber<-c("ID3413241", "ID3413242", "ID3413243", "ID3413244")

#Create a named list.  In reality, my problem is more complex, but this gets at the root of the issue
mylistnames<-list(pathnames_in=pathnames, ListIdNumber_in=ListIdNumber)

#Functions that I've tried, where I'm passing the name ListIdNumber_in into the function so
#the resulting data frames are named.

#Attempt 1
get_data_files1<-function(pathnames_in, ListIdNumber_in){
  tempdf <- read.csv(pathnames_in) %>% set_names(nm=ListIdNumber_in)
}

#Attempt 2
get_data_files2<-function(pathnames_in, ListIdNumber_in){
  tempdf <- read.csv(pathnames_in) 
  names(tempdf)<-ListIdNumber_in
  tempdf
}

#Attempt 3
get_data_files3<-function(pathnames_in, ListIdNumber_in){
  tempdf <- read.csv(pathnames_in) 
  tempdf
}

#Fails
pmap(mylistnames, get_data_files1)->myoutput1

#Almost, but doesn't name the tibbles it creates and instead creates a variable named ListIdNumber_in
pmap(mylistnames, get_data_files2)->myoutput2

#This gets me the end result that I want, but I want to set the names inside the function
pmap(mylistnames, get_data_files3) %>% set_names(nm=mylistnames$ListIdNumber_in)->myoutput3

Donc, quand j'exécute pmap, j'aimerais obtenir le résultat suivant, seulement je voudrais que le nom des trames de données / tibbles imbriqués soit fait dans la fonction (et je n'ai pas vraiment besoin du 'X 'variable qui, je pense, est créée par erreur):

$ID3413241
  X var1 var2
1 1   22   43
2 2   43   45

$ID3413242
  X var1 var2
1 1   42   43
2 2   43   45

$ID3413243
  X var1 var2
1 1   90   97
2 2   98   96

$ID3413244
  X var1 var2
1 1   43   85
2 2   55   43

Des idées comment cela peut être accompli?

Merci!

0
StatsStudent 24 sept. 2020 à 06:23

2 réponses

Meilleure réponse

Pourquoi ne pas créer votre propre pmap à cet effet?

# assume that your names are always stored in `ListIdNumber_in`
named_pmap <- function(.l, .f, ...) set_names(pmap(.l, .f, ...), .l$ListIdNumber_in)

Ensuite, vous pouvez appeler directement named_pmap(mylistnames, get_data_files3). Sauf pour la partie nommage, ce named_pmap est fondamentalement le même que pmap.

2
ekoam 24 sept. 2020 à 05:27
  • Utilisez map ici
  • Pas besoin de créer une liste nommée puisque vous ne pouvez pas attacher de noms au niveau supérieur lors de la lecture du csv, ajoutez des noms séparément.
library(purrr)
map(pathnames, read.csv) %>% set_names(ListIdNumber)

#$ID3413241
#  var1 var2
#1   22   43
#2   43   45

#$ID3413242
#  var1 var2
#1   42   43
#2   43   45

#$ID3413243
#  var1 var2
#1   90   97
#2   98   96

#$ID3413244
#  var1 var2
#1   43   85
#2   55   43

En base R, cela peut être fait comme:

setNames(lapply(pathnames, read.csv), ListIdNumber)

La raison pour laquelle vous obtenez une colonne X supplémentaire est que lorsque vous écrivez le csv, vous écrivez également des noms de fichiers. Réglez-le sur row.names = FALSE et vous n'aurez pas cette colonne.

write.csv(x=data.frame(var1=c(42,43),var2=c(43,45)), 
          file="C:\\temp\\AL.csv", row.names = FALSE)
2
Ronak Shah 24 sept. 2020 à 03:44