2010-11-12 10 views
4

Je suis novice en programmation et j'ai écrit un code qui trouve des mots de spam pour le premier email mais j'aimerais écrire une boucle for qui le ferait pour tous les emails. Toute aide serait appréciée. Je vous remercie.comment démarrer une boucle for dans la programmation R

words = grepl("viagra", spamdata[[ 1 ]]$header[ "Subject"]) 
+10

Avez-vous consulté le manuel 'Introduction à R' fourni avec votre installation? –

+0

Il y a un certain nombre de façons d'accomplir ce que vous cherchez, avec des boucles pour être l'un des moyens les moins efficaces de le faire. En lisant le manuel, Dirk suggère de faire attention aux expressions telles que la vectorisation et d'appliquer des fonctions. –

+0

J'espère que ce n'est pas pour un projet de classe. Je connais quelques personnes qui utilisent ces données de spam ... – hadley

Répondre

0

Dans R a loopstakes cette forme, où la variable est le nom de la variable d'itération, et la séquence est un vecteur ou d'une liste de valeurs:

pour (variable dans la séquence) expression

Le expression peut être une seule commande R - ou plusieurs lignes de commandes enveloppé dans des accolades:

for (variable in sequence) { 
    expression 
    expression 
    expression 
} 

dans ce cas, il serait pour (mots) {faire ce que vous voulez faire}

également

théorie boucle de base

La structure de base pour les commandes de boucle est: for(i in 1:n){stuff to do}, où n est le nombre de fois que la boucle sera exécutée.

listname[[1]] se réfère au premier élément de la liste « listname. »

Dans une boucle for, listname[[i]] se réfère à la variable correspondant à la ième itération de la boucle for.

Le code for(i in 1:length(yesnovars)) indique à la boucle de s'exécuter une seule fois pour chaque variable de la liste.

Réponse prise des sources suivantes:
Loops in R
Programming in R

+0

La deuxième partie est une copie textuelle de http: //dataninja.wordpress.com/2006/02/01/lists-in-r/ –

+0

La première partie est une copie textuelle de http://www2.warwick.ac.uk/fac/sci/moac/degrees/modules/ch923/r_introduction/r_programming/ –

+0

J'espère gagner les loopstakes bientôt. –

15

Je suppose que vous voulez faire une boucle sur les éléments de spamdata et de construire un indicateur si la chaîne "viagra" se trouve dans les lignes d'objet de vos e-mails.

permet de configurer des données fictives à des fins d'illustration:

subjects <- c("Buy my viagra", "Buy my Sildenafil citrate", 
       "UK Lottery Win!!!!!") 
names(subjects) <- rep("Subject", 3) 
spamdata <- list(list(Header = subjects[1]), list(Header = subjects[2]), 
       list(Header = subjects[3])) 

Ensuite, nous créons un vecteur words pour tenir le résultat de chaque itération de la boucle. Vous ne voulez pas augmenter words ou tout autre objet à chaque itération - cela forcera la copie et ralentira votre boucle. Au lieu de cela allouer de la mémoire avant de commencer - ici en utilisant la longueur de la liste sur laquelle nous voulons boucle:

words <- logical(length = length(spamdata)) 

Vous pouvez configurer une boucle comme si

## seq_along() creates a sequence of 1:length(spamdata) 
for(i in seq_along(spamdata)) { 
    words[ i ] <- grepl("viagra", spamdata[[ i ]]$Header["Subject"]) 
} 

On peut alors regarder words:

> words 
[1] TRUE FALSE FALSE 

Ce qui correspond à ce que nous savons des sujets inventés.

Remarquez comment nous avons utilisé i comme support de place pour 1, 2 et 3 - à chaque itération de la boucle, i prend la valeur suivante dans la séquence 1, 2, 3 afin que nous puissions i) accéder au i le composant de spamdata pour obtenir la ligne d'objet suivante, et ii) accéder à l'élément i e de words pour stocker le résultat de l'appel grepl(). Notez qu'à la place d'une boucle implicite, nous pourrions également utiliser les fonctions sapply() ou lapply(), qui créent la boucle pour vous mais peuvent nécessiter un peu de travail pour écrire une fonction personnalisée. Au lieu d'utiliser grepl() directement, nous pouvons écrire un wrapper:

foo <- function(x) { 
    grepl("viagra", x$Header["Subject"]) 
} 

Dans la fonction ci-dessus, nous utilisons x au lieu du nom de la liste spamdata parce que quand lapply() et boucle sapply() sur la liste spamdata, les composants individuels (référencés par spamdata[[i]] dans la boucle for()) est passé à notre fonction comme argument x de sorte que nous avons seulement besoin de se référer à x dans l'appel grepl().

Voici comment nous pourrions utiliser notre fonction enveloppe foo() dans lapply() ou sapply(), d'abord lapply():

> lapply(spamdata, foo) 
[[1]] 
[1] TRUE 

[[2]] 
[1] FALSE 

[[3]] 
[1] FALSE 

sapply() simplifiera l'objet retourné lorsque cela est possible, comme suit:

> sapply(spamdata, foo) 
[1] TRUE FALSE FALSE 

Autre que ça, ils fonctionnent de la même manière.

Remarque, nous pouvons rendre notre fonction enveloppe foo() plus utile en lui permettant de prendre un argument définissant le spam mot que vous souhaitez rechercher:

foo <- function(x, string) { 
    grepl(string, x$Header["Subject"]) 
} 

Nous pouvons passer des arguments supplémentaires à nos fonctions avec lapply() et sapply() comme ceci:

> sapply(spamdata, foo, string = "viagra") 
[1] TRUE FALSE FALSE 
> sapply(spamdata, foo, string = "Lottery") 
[1] FALSE FALSE TRUE 

que vous trouverez le plus utile (boucle for() ou lapply(), sapply() versions) w Je vais dépendre de vos antécédents de programmation et que vous trouvez le plus familier. Parfois, for() est plus facile et plus simple à utiliser, mais peut-être plus verbeux (ce qui n'est pas toujours une mauvaise chose!), Tandis que lapply() et sapply() sont assez succincts et utiles où vous n'avez pas besoin de sauter à travers les cerceaux pour créer une fonction wrapper .

Questions connexes