Additionner les lignes en fonction de la valeur de colonne correspondante dans R? [dupliquer]

Aug 16 2020
        c1       c2       count 
 1        1        1          20
 2        2        3          50 
 3        1        4          30              

Donc, j'ai essentiellement des données comme le tableau ci-dessus, mais ce que je veux faire est d'ajouter une nouvelle colonne qui divise le nombre de lignes par la somme des nombres de toutes les lignes avec la même valeur c1, se terminant par quelque chose comme:

        c1       c2       count    new_col
 1        1        1          20     20/50
 2        2        3          40     40/40
 3        1        4          30     30/50

Comme vous pouvez le voir, la nouvelle colonne a le nombre de lignes divisé par la somme de tous les nombres avec la valeur c1 correspondante. Donc, ce que j'ai essayé est quelque chose comme ça:

df$new_col <- df$count/sum(df[SUBSET OF ROWS THAT HAVE SAME c1 VALUE]$count)

J'ai vu quelque chose comme df [df $ c1 == une valeur,] mais cela ne fonctionnerait que pour une valeur codée en dur. Je pourrais aussi essayer d'utiliser une boucle for, mais cela prend beaucoup trop de temps pour parcourir chaque ligne de mes données et ne finit jamais de fonctionner, je ne connais pas non plus toutes les valeurs prises par c1. Je suis assez nouveau dans R et il y a peut-être une solution très simple à cela, mais je n'ai pas été en mesure de la trouver.

Réponses

3 Duck Aug 16 2020 at 04:06

Essaye ça:

library(dplyr)
#Data
df <- structure(list(c1 = c(1L, 2L, 1L), c2 = c(1L, 3L, 4L), count = c(20, 
40, 30)), row.names = c("1", "2", "3"), class = "data.frame")

Le code:

df %>% group_by(c1) %>% mutate(Sum=sum(count),NewVar=count/Sum)

Production:

# A tibble: 3 x 5
# Groups:   c1 [2]
     c1    c2 count   Sum NewVar
  <int> <int> <dbl> <dbl>  <dbl>
1     1     1    20    50    0.4
2     2     3    40    40    1  
3     1     4    30    50    0.6
2 ThomasIsCoding Aug 16 2020 at 04:20

Une option de base R via ave

> within(df,new_col <- count/ave(count,c1,FUN = sum))
  c1 c2 count new_col
1  1  1    20     0.4
2  2  3    40     1.0
3  1  4    30     0.6

ou via rowsum(par @akrun à partir du commentaire)

> within(df,new_col <- count/rowsum(count,c1)[c1])
  c1 c2 count new_col
1  1  1    20     0.4
2  2  3    40     1.0
3  1  4    30     0.6

Les données

> dput(df)
structure(list(c1 = c(1L, 2L, 1L), c2 = c(1L, 3L, 4L), count = c(20, 
40, 30)), row.names = c("1", "2", "3"), class = "data.frame")