J'ai le code suivant dans une fonction
Myfunc<- function(directory, MyFiles, id = 1:332) {
# uncomment the 3 lines below for testing
#directory<-"local"
#id=c(2, 4)
#MyFiles<-c(f2.csv,f4.csv)
idd<-id
df2 <- data.frame()
for(i in 1:length(idd)) {
EmptyVector <- read.csv(MyFiles[i])
comp_cases[i]<-sum(complete.cases(EmptyVector))
print(comp_cases[[i]])
id=idd[i]
ret2=comp_cases[[i]]
df2<-rbind(df2,data.frame(id,ret2))
}
print(df2)
return(df2)
}
Cela fonctionne lorsque j'essaie de l'exécuter dans R en sélectionnant le code dans la fonction et en commentant le retour. Je reçois un cadre de données Nice comme à partir de l'instruction print:
> df2
id ret2
1 2 994
2 4 7112
Cependant, lorsque j'essaie de renvoyer le dataframe df2
à partir de la fonction, il ne renvoie que la 1ère ligne, en ignorant toutes les autres valeurs. Mon problème est que cela fonctionne dans la fonction pour différentes valeurs que j'ai essayées (ouvrir plusieurs fichiers avec différentes combinaisons) et pas lorsque j'essaie de retourner le bloc de données. Quelqu'un peut aider s'il vous plaît. Merci beaucoup d'avance.
Si je vous ai bien compris, vous essayez de créer une base de données avec le nombre de cas complets pour chaque id
. En supposant que vos fichiers soient des noms avec les numéros d'identification que vous avez spécifiés (par exemple, f2.csv
), vous pouvez simplifier votre fonction de la manière suivante:
myfunc <- function(directory, id = 1:332) {
y <- vector()
for(i in 1:length(id)){
x <- id
y <- c(y, sum(complete.cases(
read.csv(as.character(paste0(directory,"/","f",id[i],".csv"))))))
}
df <- data.frame(x, y)
colnames(df) <- c("id","ret2")
return(df)
}
Vous pouvez appeler cette fonction comme ceci:
myfunc("name-of-your-directory",25:87)
Une explication du code ci-dessus. Vous devez décomposer votre problème en étapes:
x <- id
id
vous voulez le nombre de cas complets. Pour obtenir cela, vous devez d'abord lire le fichier. Cela se fait par read.csv(as.character(paste0(directory,"/","f",id[i],".csv")))
. Pour obtenir le nombre d'observations complètes pour ce fichier, vous devez insérer le code read.csv
dans sum
et complete.cases
.y <- vector()
) auquel vous pouvez ajouter le nombre d'observations complètes à partir de l'étape 2. Cela est fait en encapsulant le code de l'étape 2 dans y <- c(y, "code step 2")
. Avec cela, vous ajoutez le nombre d'observations complètes pour chaque id
au vecteur y
.df <- data.frame(x, y)
et à attribuer une signification colnames
.En incluant les étapes 1, 2 et 3 (à l'exception de la partie y <- vector()
) dans une boucle for, vous pouvez parcourir la liste des identifiants spécifiés. La création du vecteur vide avec y <- vector()
doit être effectuée avant la boucle for, afin que celle-ci puisse ajouter des valeurs à y
.
Celui-ci est en fait assez facile à contourner en changeant de périmètre.
Le problème est que vous créez initialement la structure de données initiale en tant que variable locale, puis que vous remplacez simplement les lignes, de sorte que vous obtiendrez uniquement les premier et dernier résultats dans la structure de données.
Lorsque je crée une boucle for avec R et que je veux ajouter les résultats de requêtes successives, etc., à un cadre de données initial, je le fais:
function(<some_args>){
main_dataframe <<- do something to generate the first set of results from
whatever you want to iterate, like 1:10, a given list, etc. and create the
initial dataframe from the first iteration and use the global assignment
('<<-'), not '<-' or '='
main_dataframe <<- do_something(whatever_you're_iterating_over[1])
for (i in 2:length(whatever_you're_iterating_over)) {
next_dataframe = do_something(whatever_you're_iterating_over[i])
main_dataframe <<- rbind(main_dataframe, next_dataframe)
}
}
La portée permettra à chaque itération de créer un cadre de données que vous pouvez ajouter à l’original sans perdre aucune des itérations entre la première et la dernière.