2009-09-22 5 views
5

Comment ajouter les valeurs de plusieurs variables?Ajout de plusieurs colonnes, transformation avec plusieurs variables

Si je viens d'avoir deux variables (colonnes) Je pourrais simplement aller:

summation.variable <- variable1 + variable2 

ou si elle était dans une trame de données:

transform(dataframe, summation.col = column1 + column2) 

Comment puis-je faire si j'ai au sujet 10 variables et je ne veux pas taper chacun comme dans col1 + col2 + col3 + col4. Pour aggraver les choses, mes colonnes ont des noms assez longs et parfois les colonnes exactes que j'utilise peuvent changer. J'ai un vecteur de caractère avec tous les noms de colonnes, mais je ne sais pas comment l'utiliser.

Ce qui suit est inutile car il ajoute chaque valeur dans chaque colonne de chaque ligne et donne une seule valeur pour le lot entier.

sum(metrics) 
+0

vérifier l'orthographe de la variable sur la ligne 2 –

Répondre

8

Vous voulez utiliser rowSums

tmp <- data.frame(a=1:2,b=3:4,d=5:6) 
rowSums(tmp[,c("a","d")]) 

ou, plus généralement, appliquer (voir l'indexation avec un vecteur de caractères.):

apply(tmp[,c("a","d")], 1, sum) 
1

Je viens de recevoir la réponse. Je savais que je voulais une sorte de somme. Je suis allé au R aider à rechercher "somme". Et là je l'ai trouvé. La réponse est de suivre le lien "colSums" à "rowSums". Donc, où metrics est un vecteur de caractères des noms de colonne pertinents. La ligne suivante produit un vecteur où tous les nombres sont ajoutés sur chaque ligne.

rowSums(data.frame[metrics]) 

Comment le faire si on voulait que chaque valeur soit multipliée les unes par rapport aux autres? Je ne vois pas de ligneProduits.

+0

Je pense que j'utiliserais la fonction apply pour faire des produits (ou une autre fonction), vérifiez? Apply – PaulHurleyuk

+0

rowSums est une version plus efficace de apply pour les sommations – Thierry

4

Il y a plusieurs façons de faire ce genre d'opération (c.-à-appliquer une fonction sur une ligne ou d'une colonne.), Mais comme Eduardo souligne, appliquer est le plus fondamental:

tmp <- data.frame(a=1:2,b=3:4,d=5:6) 
apply(tmp, 1, prod) 

C'est très fonction flexible. Par exemple, vous pouvez faire les deux opérations à la fois avec cet appel:

apply(tmp, MARGIN=1, function(x) c(sum(x), prod(x))) 

à la même analyse sur plusieurs colonnes est également simple (le paramètre MARGE indique si vous utilisez des lignes ou des colonnes):

apply(tmp, MARGIN=2, function(x) c(sum(x), prod(x))) 
3

Répondre à Farrel answer:

Sur RSeek pour rowProd j'ai trouvé deux packages - matrixStats et fUtilities. Vous pourriez les regarder.

La deuxième solution est un peu complexe. Vous pouvez créer votre expression et les évaluer.

X <- structure(list(
    varA = c(0.98, 0.75, -0.56, -1.43, 0.65, -1.15, -1.52, 0.1, 0.06, 0.76), 
    varB = c(-0.12, -0.6, 0.62, 0.9, -0.44, 0.37, 0.62, 0.76, -1.61, -0.26), 
    varC = c(-0.5, -0.37, -0.43, -0.7, 0.83, -0.24, -0.57, 0.05, -1.31, 0.7), 
    varD = c(-0.06, -0.11, 1.03, -1.76, -0.42, -1.21, -0.62, -1, -1.16, 2.13), 
    varE = c(-1.96, 0.69, -1.85, -1.74, -1.47, 1.24, 0.29, -1.18, 0.89, 0.42), 
    varF = c(0.29, -0.22, -1.29, 1.19, 0.38, -0.23, -0.5, -1.07, -1.83, 0.58), 
    varG = c(0.59, -0.41, -1.37, 0.89, -0.75, 0.95, 0.95, -0.9, 0.71, -1.3) 
), 
    .Names = c("varA", "varB", "varC", "varD", "varE", "varF", "varG"), 
    row.names = c(NA, -10L), class = "data.frame" 
) 

metrics <- c("varB","varC","varF") 

eval(
    parse(text = paste(metrics,collapse=" * ")), 
    envir = X 
) 

Quelques explications:

  • pâte créer une chaîne ressemble varB * Varc * varF (effondrement est pour concaténer éléments de vecteur)
  • Parse est de convertir le texte à l'expression
  • eval avec envir = X est d'exécuter l'expression dans X

Pour votre question originale, vous pouvez utiliser col lapse = "+".

edit: si vos variables ne sont pas dans un data.frame alors eval sans envir suffit.

Edit2: exemples d'utilisation rowProds de paquets mentionnés:

matrixStats::rowProds(as.matrix(X[,metrics])) # convert to a matrix is needed 
fUtilities::rowProds(X[,metrics]) # without conversion 

Je digg dans la source cette fonction et:

  • futilités utilisent appliquer, c'est donc la même que celle applicable (X, 1 , prod) (ce n'est pas une soulution efficace)
  • matriceStats est intelligent et fait quelque chose comme exp (rowSums (log (X))), devrait donc être plus rapide.

tests de vitesse:

Xm <- matrix(rnorm(50000*8),ncol=8) 
Xd <- as.data.frame(Xm) 

require(fUtilities) 
require(matrixStats) 
system.time(matrixStats::rowProds(as.matrix(Xd))) 
# user system elapsed 
# 0.08 0.02 0.09 
system.time(matrixStats::rowProds(Xm)) 
# user system elapsed 
# 0.08 0.00 0.08 
system.time(fUtilities::rowProds(Xd)) 
# user system elapsed 
# 0.52 0.00 0.52 

Même avec la conversion à une version matrice de matrixStats est plus rapide.

+1

library (fortunes) ; fortune (106) – Thierry

+0

Je veux utiliser do.call (f, as.list (X [, metrics])) mais je ne trouve pas de fonction fonctionnant comme f (a, b, c) = a * b * c. Bon commentaire btw;) – Marek

+0

Regardez 'prod()' – hadley

Questions connexes