2016-05-24 3 views
1

Essayer d'effectuer une opération sur chaque colonne dans une trame de données. Pas sûr d'utiliser apply ou for (pas sûr de savoir comment ignorer la première colonne en apply).R pour une boucle ou pour appliquer des colonnes de table de données

Question 1:

Pour imprimer simplement chaque nom deux fois j'ai compris:

for (i in names(dt)){if(str_length(i) < 3) {print(i);print(i)}}

Le premier nom de colonne est la seule avec une longueur de chaîne> 3, qui est la raison pour laquelle je utilisé ça.

J'ai essayé d'utiliser:

for (i in dt$i){if(str_length(names(i)) < 3) {print(i);print(i)}} 
for (i in dt$i){if(str_length(names(dt)) < 3) {print(i);print(i)}} 

Pour imprimer simplement deux fois par colonne, mais juste créé une valeur vide.

Question 2:

Ce que je fait faire au lieu d'imprimer deux fois; est de commander chaque colonne: order(-i) ??

Ensuite, créez un sous-ensemble: head(i, n=500) ??

Vous ne savez pas s'il s'agit d'une étape supplémentaire ou d'une extension de l'étape ci-dessus. Puis définissez cela comme un data.frame; dt(i) < data.frame(head(i, n=500)) ??

Puis enregistrer cette table: write.csv(dt(i), "newfolder/i.csv", row.names = FALSE) - Je pense que cela va remplacer constamment un fichier appelé i.csv, je ne sais pas comment je nommerais le fichier basé sur i.

Peut-être apply est une meilleure approche, je ne suis pas sûr. Je simplifierais l'approche (telle que je comprends ce qui se passe) serait appréciée. J'ai seulement 40 colonnes, chacune avec 50 000 lignes, donc ça ne devrait pas être aussi lent.

EDIT

Essayer d'être plus clair, je vais ajouter un exemple:

Name Math Science PE 
David 90 70 25 
Tom 100 60 40 
John 30 40 100 

je voudrais terminer par 3 csv de avec la première recherche comme:

Name Math 
Tom 100 
David 90 

Dans le cas ci-dessus n = 2 pour la tête. Le csv pourrait aussi avoir les autres colonnes, mais elles ne sont pas obligatoires.

+1

'ne sais pas comment je le nom du fichier basé sur i . '- utiliser' paste0 ("myFile", i, ".csv") ' – zx8754

+2

Votre message n'est pas très clair et peut-être fermé comme trop large. Veuillez ajouter les données d'entrée et la sortie attendue. 'apply' est juste une version prétendue de' for loop', donc c'est à vous de l'utiliser. – zx8754

+0

Est-ce que mon édition était suffisante? –

Répondre

3

Utilisation de vos données fictives, nous pouvons boucle par « sujet » colonnes 2: n, puis trier et écrire 2 meilleurs résultats:

# dummy data 
df <- read.table(text="Name Math Science PE 
David 90 70 25 
Tom 100 60 40 
John 30 40 100", header = TRUE) 


# loop and write csv for top 2 scores 
lapply(colnames(df)[2:ncol(df)], function(i){ 
    res <- df[, c("Name", i)] 
    res <- res[order(res[, i], decreasing = TRUE),] 
    write.csv(head(res, 2), file = paste0(i, ".csv")) 
}) 
2

Essayez quelque chose comme ceci (en utilisant mtcars comme exemple):

mtcars[] <- lapply(mtcars, sort) 
head(mtcars) 

Ici, vous trier chaque colonne du plus petit au plus grand. Notez que chaque ligne individuelle n'est plus utile, car elle ne représente pas une unité particulière. Vous obtenez cependant votre sortie souhaitée. Ensuite, vous pouvez simplement utiliser head() pour obtenir le nombre d'entrées souhaité.

Pour voir ce qui se passe:

D'abord, comment le regard des données d'origine:

> head(mtcars) 
        mpg cyl disp hp drat wt qsec vs am gear carb 
Mazda RX4   21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 
Mazda RX4 Wag  21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 
Datsun 710  22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 
Valiant   18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 

Maintenant, nous allons trier chaque colonne:

> mtcars[] <- lapply(mtcars, sort) 

Qu'est-ce que la sortie ressemble:

> head(mtcars, 5) 
        mpg cyl disp hp drat wt qsec vs am gear carb 
Mazda RX4   10.4 4 71.1 52 2.76 1.513 14.50 0 0 3 1 
Mazda RX4 Wag  10.4 4 75.7 62 2.76 1.615 14.60 0 0 3 1 
Datsun 710  13.3 4 78.7 65 2.93 1.835 15.41 0 0 3 1 
Hornet 4 Drive 14.3 4 79.0 66 3.00 1.935 15.50 0 0 3 1 
Hornet Sportabout 14.7 4 95.1 66 3.07 2.140 15.84 0 0 3 1 

Vous constatez également que les noms usuels ne sont plus informatifs. S'il vous plaît assurez-vous que c'est ce que vous voulez. Pour enregistrer les 500 plus petites lignes de votre nouvelle base de données, utilisez simplement des sous-ensembles réguliers, tels que df[1:500,].

Pour garder les noms, nous pouvons générer une liste de dataframes à la place:

newdat <- lapply(mtcars, function(x){ 
    dat <- data.frame(ind = rownames(mtcars), out = x) 
    dat <- dat[order(dat$out),] 
}) 

Ici, la sortie sera une liste avec les anciens rownames (appelés ind) et la colonne ordonnée appelée out. C'est une liste nommée, où chaque élément de la liste correspond au nom de la colonne d'origine. Notez que vous pouvez utiliser la structure list plus loin, comme dans lapply(newdat, head).

+0

Je veux que le nom de la ligne change lorsque chaque colonne est triée, puis-je utiliser apply dans une boucle for then? La première colonne est une charge de variable et chaque autre colonne représente un secteur différent. Pour chaque secteur, j'essaie d'ordonner les variables et de sauvegarder les variables supérieures, de sorte qu'après cela j'écrirai une autre boucle pour tracer chaque secteur. espérons que cela a du sens –

+0

@OliPaul ajouter des noms comme une nouvelle colonne, puis trier. 'mtcars $ myNames <- noms de famille (mtcars)', puis faites le tri. – zx8754

+0

Ils le sont déjà, mais lors du tri dans la boucle, les noms ne sont pas des valeurs et je ne voudrais pas les trier –