Consolider les doublons

J'ai un cadre de données où une colonne est les noms des espèces, et la deuxième colonne est les valeurs d'abondance. En raison de la procédure d'échantillonnage, certaines espèces apparaissent plus d'une fois (c'est-à-dire qu'il y a plus d'une rangée avec L'espèce X). Je voudrais consolider ces entrées et résumer leurs abondances.

Par exemple, étant donné cette trame de données:

set.seed(6)
df=data.frame(
  x=c("sp1","sp2","sp3","sp3","sp4","sp2","sp3"),
  y=rpois(7,2)); df

Qui produit:

    x y
1 sp1 2
2 sp2 4
3 sp3 1
4 sp3 1
5 sp4 3
6 sp2 5
7 sp3 5

Je voudrais plutôt produire:

    x y
1 sp1 2    
2 sp2 9     (5+4)
3 sp3 7     (5+1+1)
5 sp4 3

Merci d'avance pour toute aide que vous pouvez fournir!

31
r
demandé sur Paul Hiemstra 2012-04-16 23:08:58

6 réponses

Cela fonctionne:

library(plyr)
ddply(df,"x",numcolwise(sum))

En mots: (1) diviser la trame de données df par la colonne "x"; (2) pour chaque bloc, prendre la somme de chaque colonne à valeur numérique; (3) coller les résultats dans une seule trame de données. (dd dans ddply signifie "prendre un d ata image en entrée, de retour d'un d ata cadre")

Une autre approche, peut-être plus claire:

aggregate(y~x,data=df,FUN=sum)

Voir moyen rapide/élégant de construire le tableau récapitulatif de moyenne / variance pour un connexe (légèrement plus complexe) question.

37
répondu Ben Bolker 2017-05-23 11:46:58

Simple comme aggregate:

aggregate(df['y'], by=df['x'], sum)
21
répondu Joshua Ulrich 2012-04-16 19:15:39

Une solution data.table pour l'efficacité du temps et de la mémoire

library(data.table)
DT <- as.data.table(df)
# which columns are numeric 
numeric_cols <- which(sapply(DT, is.numeric))
DT[, lapply(.SD, sum), by = x, .SDcols = numeric_cols]

Ou, dans votre cas, étant donné que vous savez qu'il n'y a que la colonne 1 y que vous souhaitez additionner sur

DT[, list(y=sum(y)),by=x]
8
répondu mnel 2012-09-13 10:46:16

Un dplyr solution:

library(dplyr)
df %>% group_by(x) %>% summarise(y = sum(y))
7
répondu Carlos Cinelli 2016-01-05 13:34:22
> tapply(df$y, df$x, sum)
sp1 sp2 sp3 sp4 
  2   9   7   3 

Si cela doit être un data.frame la réponse de Ben fonctionne très bien. ou vous pouvez forcer la sortie tapply.

out <- tapply(df$y, df$x, sum)
>     data.frame(x=names(out), y=out, row.names=NULL)
    x y
1 sp1 2
2 sp2 9
3 sp3 7
4 sp4 3
6
répondu Justin 2012-04-16 19:16:27

Un MWE pour vérifier si une formule pour respecter une deuxième variable (c'est-à-dire, ici "Z" et en plus de "X", fonctionnerait réellement:

example = data.frame(X=c("x"),Z=c("a"),Y=c(1), stringsAsFactors=F)
newrow = c("y","b",1)
example <- rbind(example, newrow)
newrow = c("z","a",0.5)
example <- rbind(example, newrow)
newrow = c("x","b",1)
example <- rbind(example, newrow)
newrow = c("x","b",2)
example <- rbind(example, newrow)
newrow = c("y","b",10)
example <- rbind(example, newrow)
example$X = as.factor(example$X)
example$Z = as.factor(example$Z)
example$Y = as.numeric(example$Y)
example_agg <- aggregate(Y~X+Z,data=example,FUN=sum)
1
répondu Shadow 2016-01-05 13:31:04