8
votes

Multiplier chaque cellule d'une donnée.frame avec son poids

Ce que je veux faire est d'embarrasser simple - néanmoins je échoue.

J'ai une donnée.frame avec "caractères" et "numérics". Une des colonnes des données.frame représente les poids. P>

Je veux multiplier toutes les cellules de la trame de données avec le poids correspondant (s'il s'agit d'un numérique). P>

Comment faire Je fais cela (meilleur sans utiliser une boucle imbriquée). P>

Merci d'avance! P>

Exemple: p>

   c1   c2   w   
l1 abc  2    1
l2 dxf  1.5  0.5
l3 ghi  6    1.5


0 commentaires

4 Réponses :


5
votes

vectoriel! xxx pré>

efficacement, vous voulez c2 * w code>, mais nous devons dire à r de regarder à l'intérieur em> le cadre de données : p> xxx pré>

que nous pouvons insérer dans dat code> dans une seule ligne: p> xxx pré>

(Remplacer c3 code> avec c2 code> si vous souhaitez écraser le C2 existant code>.) P>

Si vous avez plus d'un chiffre Colonne autre que des poids, une stratégie différente glaciale est requise si vous souhaitez l'automatiser (c.-à-d. Ne pas indiquer à les colonnes à multiplier par w code>). p>

> ## dummy data
> dat2 <- data.frame(c1 = c("abc","dxf","ghi"), c2 = 2:4, w = c(1,0.5,1.5),
                     c3 = 5:7, c4 = 3:5)
> ## select the columns we want, all numerics, but not `w`
> want <- sapply(dat2, is.numeric) & names(dat2) != "w"
> ## then use want to index into dat2
> dat2[, want] <- with(dat2, dat2[, want] * w)
> dat2
   c1  c2   w   c3  c4
1 abc 2.0 1.0  5.0 3.0
2 dxf 1.5 0.5  3.0 2.0
3 ghi 6.0 1.5 10.5 7.5


3 commentaires

Je vous remercie! Je sais que cela fonctionnerait, mais j'ai environ 200 colonnes, je ne peux donc pas faire toutes ces multiplications à la main. Mais je suppose qu'il y aurait un moyen de le faire avec Appliquer ou une boucle de foresach ...


@Marcel Je n'ai pas remarqué les nombreuses colonnes une partie de la Q initialement - j'ai ajouté un exemple de faire la même chose pour de nombreuses colonnes pendant que vous écrivez votre commentaire.


ma faute - je ne l'ai pas mentionné dans ma question initiale



6
votes

pour un exemple reproductible, dd code> est une trame de données avec un mélange de types variables, avec w code> étant les poids.

dd <- data.frame(G=gl(2,2), X=rnorm(4), Y=1L:4L, Z=letters[1:4], W=0.3:3.3)
num.vars <- names(dd)[sapply(dd, is.numeric)]  #select numeric variables
num.vars <- setdiff(num.vars, "W")  # remove the weight variable
dd[num.vars] <- dd[num.vars] * dd$W  # multiply


1 commentaires

Excellente technique pour extraire des colonnes numériques, puis les réinsérer. Merci!



2
votes

Juste pour le plaisir d'essayer de le faire en une seule ligne (mais vraiment pas le plus lisible!): xxx


1 commentaires

Je l'ai essayé d'une manière ou d'une autre comme toi, mais j'ai échoué! Je vais regarder cela très soigneusement! :)



1
votes

Comme vous l'avez vu, il y a un certain nombre de façons de le faire, mais vous vous attendriez d'une manière ou d'une autre manière que vous vous attendiez à un moyen très simple et que je ne sais pas si cela existe. Il existe une fonction de bibliothèque dans le paquet Plyr intitulé Colwise qui est proche, mais je ne peux pas trouver un moyen propre pour le faire faire exactement ce que vous voulez. Le mieux que je puisse faire WTIH Colwise, c'est ceci (en supposant que votre Dataframe est nommé DF): xxx

w2 <-df $ w df <-colwise (fonction (x, w) {if.numeric (x)) {x * w} else {x}}}) (DF, df $ w) df $ w <-w2

pour ceux qui sont familiers avec Versement, je ne pense pas que vous puissiez simplement utiliser numcolwise car les colonnes non numériques ne sont pas émises du tout . Et je ne peux pas comprendre un moyen propre de ne pas avoir la multiplication applicable au poids, c'est pourquoi je l'enregistre et le restaure simplement ici. Je pense que si une manière plus propre de faire cela peut être élaborée, Colwise est une belle simlpe et facile à comprendre le moyen de le faire.


1 commentaires

Je vous remercie! J'ai vraiment pensé qu'il y avait une simple commande qui ferait tout, mais peu importe, au moins j'ai appris quelque chose ...