107 votes

Additionner les lignes dans un data.frame ou une matrice

J'ai un très grand dataframe avec des lignes comme observations et des colonnes comme marqueurs génétiques. Je voudrais créer une nouvelle colonne qui contient la somme d'un certain nombre de colonnes sélectionnées pour chaque observation en utilisant R.

Si j'ai 200 colonnes et 100 lignes, alors je voudrais créer une nouvelle colonne qui a 100 lignes avec la somme par exemple des colonnes 43 à 167. Les colonnes ont soit 1 soit 0. Avec la nouvelle colonne qui contient la somme de chaque ligne, je pourrai trier les individus qui ont le plus de marqueurs génétiques.

Je pense que cela ressemble à quelque chose comme:

data$new=sum(data$[,43:167])

144voto

Greg Points 4344

Vous pouvez utiliser rowSums

rowSums(data) devrait vous donner ce que vous voulez.

51voto

Greg Snow Points 22040

La fonction rowSums (comme le mentionne Greg) fera ce que vous voulez, mais vous mélangez les techniques de sous-ensemble dans votre réponse, ne pas utiliser "$" lors de l'utilisation de "[]", votre code devrait ressembler davantage à :

data$new <- rowSums( data[,43:167] )

Si vous voulez utiliser une fonction autre que sum, alors regardez ?apply pour appliquer des fonctions générales aux lignes ou aux colonnes.

11voto

seeiespi Points 48

Je suis venu ici en espérant trouver un moyen d'obtenir la somme de toutes les colonnes d'un tableau de données et j'ai rencontré des problèmes en mettant en œuvre les solutions ci-dessus. Une façon d'ajouter une colonne avec la somme de toutes les colonnes utilise la fonction cbind :

cbind(data, total = rowSums(data))

Cette méthode ajoute une colonne total aux données et évite le problème d'alignement rencontré lorsqu'on essaie de faire la somme de TOUTES les colonnes en utilisant les solutions ci-dessus (voir le post ci-dessous pour une discussion de ce problème).

Ajout d'une nouvelle colonne à l'erreur de la matrice

6voto

rubengavidia0x Points 139

Juste pour complétude. Je vais lister d'autres méthodes non mentionnées ici c'est différentes façons de le faire la même chose en utilisant la syntaxe dplyr avec une matrice :

mat = matrix(1:12, ncol = 3)

library(dplyr)

mat %>% as_tibble() %>% 
   mutate(sum = rowSums(across(where(is.numeric))))

# A tibble: 4 x 4
     V1    V2    V3   sum

1     1     5     9    15
2     2     6    10    18
3     3     7    11    21
4     4     8    12    24

ou c_across:

mat %>% as_tibble() %>%
  rowwise() %>% 
  mutate(sumrange = sum(c_across(), na.rm = T))

ou en sélectionnant des colonnes spécifiques par le nom de la colonne :

mat %>% as_tibble() %>%
    mutate( 'B1' = V1, B2 = V2) %>% 
    rowwise() %>% 
    mutate(sum_startswithB = 
sum(c_across(starts_with("B")), na.rm = T))

     V1    V2    V3    B1    B2 sum_startswithx

1     1     5     9     1     5               6
2     2     6    10     2     6               8
3     3     7    11     3     7              10
4     4     8    12     4     8              12 

par index de colonne dans ce cas de la première colonne à la quatrième colonne :

mat %>% as_tibble() %>%
  mutate( 'B1' = V1, B2 = V2) %>%
  rowwise() %>% 
  mutate(SumByIndex = sum(c_across(c(1:4)), na.rm = T))

     V1    V2    V3    B1    B2 SumByIndex

1     1     5     9     1     5         16
2     2     6    10     2     6         20
3     3     7    11     3     7         24
4     4     8    12     4     8         28

En utilisant l'expression régulière :

mat %>% as_tibble() %>%
  mutate( 'B1' = V1, B2 = V2) %>%
  mutate(sum_V = rowSums(.[grep("V[2-3]", names(.))], na.rm = TRUE),
  sum_B = rowSums(.[grep("B", names(.))], na.rm = TRUE))

     V1    V2    V3    B1    B2 sum_V sum_B

1     1     5     9     1     5    14     6
2     2     6    10     2     6    16     8
3     3     7    11     3     7    18    10
4     4     8    12     4     8    20    12

En utilisant la fonction Apply est plus pratique car vous pouvez choisir la somme, la moyenne, le max, le min, la variance et l'écart type des colonnes.

mat %>% as_tibble() %>%
  mutate( 'B1' = V1, B2 = V2) %>%
  mutate(sum = select(., V1:B1) %>% apply(1, sum, na.rm=TRUE)) %>%
  mutate(mean = select(., V1:B1) %>% apply(1, mean, na.rm=TRUE)) %>%
  mutate(max = select(., V1:B1) %>% apply(1, max, na.rm=TRUE)) %>%
  mutate(min = select(., V1:B1) %>% apply(1, min, na.rm=TRUE)) %>%  
  mutate(var = select(., V1:B1) %>% apply(1, var, na.rm=TRUE)) %>%
  mutate(sd = select(., V1:B1) %>% apply(1, sd, na.rm=TRUE))

     V1    V2    V3    B1    B2   sum  mean   max   min   var    sd

1     1     5     9     1     5    16     4     9     1  14.7  3.83
2     2     6    10     2     6    20     5    10     2  14.7  3.83
3     3     7    11     3     7    24     6    11     3  14.7  3.83
4     4     8    12     4     8    28     7    12     4  14.7  3.83

Remarque : la sortie de la variance et de l'écart type identique n'est pas une erreur car les données sont générées de manière linéaire 1:12 vous pouvez vérifier en calculant les valeurs de la première colonne :

> sd(c(1,5,9,1))
[1] 3.829708
> sd(c(2,6,10,2))
[1] 3.829708

3voto

Phoenix Points 384

Je vais essayer de vous aider en donnant le temps écoulé pour chaque méthode en prenant un exemple :

mat = matrix(runif(4e6), ncol = 50)

Comparaison entre la fonction apply et rowSums :

apply_func <- function(x) {
    apply(x, 1, sum)
}

r_sum <- function(x) {
    rowSums(x)
}

# Comparer les méthodes
microbenchmark(
    apply_func = app(mat),
    r_sum = r_sum(mat), times = 1e5
)

------ résultat -- en millisecondes --------

       expr       min        lq      mean    median        uq      max neval
 apply_func 207.84661 260.34475 280.14621 279.18782 294.85119 354.1821   100
      r_sum  10.76534  11.53194  13.00324  12.72792  14.34045  16.9014   100

Comme vous le remarquez, le temps moyen pour la fonction rowSums est 21 fois plus petit que le temps moyen de la fonction apply. Vous verrez que la différence dans le temps écoulé peut être encore plus significative si la matrice a trop de colonnes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X