Salut, pouvez-vous expliquer comment je peux fusionner deux tables pour les utiliser pour générer un diagramme à morceaux?
#read input data dat = read.csv("/ramdisk/input.csv", header = TRUE, sep="\t") # pick needed columns and count the occurences of each entry df1 = table(dat[["C1"]]) df2 = table(dat[["C2"]]) # rename columns names(df1) <- c("ID", "a", "b", "c", "d") names(df2) <- c("ID", "e", "f", "g", "h") # show data for testing purpose df1 # ID a b c d #241 18 17 28 29 df2 # ID e f g h #230 44 8 37 14 # looks fine so far, now the problem: # what I want to do ist merging df and df2 # so that df will contain the overall numbers of each entry # df should print # ID a b c d e f g h #471 18 17 28 29 44 8 37 14 # need them to make a nice piechart in the end #pie(df)
Je suppose que cela peut être fait avec fusion d'une manière ou d'une autre, mais je ne l'ai pas fait trouvé le bon chemin. La solution la plus proche que j'ai trouvée était la fusion (df1, df2, all = TRUE), mais ce n'était pas exactement ce dont j'avais besoin.
3 Réponses :
Une approche serait de empiler
, puis de rbind
et de faire un aggregate
rowsum(v1, group = names(v1))
pour obtenir un vector
v1 <- c(df1, df2) tapply(v1, names(v1), sum)
Une autre approche consiste à concaténer les tables puis à utiliser tapply
pour faire un grouper par sum
with(out, setNames(values, ind))
Ou avec rowsum
out <- aggregate(values ~ ., rbind(stack(df1), stack(df2)), sum)
p >
Une autre approche serait d'utiliser rbindlist
de data.table
et colSums
pour obtenir les totaux. rbindlist
avec fill = TRUE
accepte toutes les colonnes, même si elles ne sont pas présentes dans les deux tables.
df1<-read.table(text="ID a b c d 241 18 17 28 29 ",header=TRUE) df2<-read.table(text="ID e f g h 230 44 8 37 14" ,header=TRUE) library(data.table) setDT(df1) setDT(df2) res <- rbindlist(list(df1,df2), use.names=TRUE, fill=TRUE) colSums(res, na.rm=TRUE) ID a b c d e f g h 471 18 17 28 29 44 8 37 14
J'ai écrit le package safejoin
qui gèrent ce type de tâches de manière intuitive (j'espère!). Il vous suffit d'avoir un identifiant commun entre vos 2 tables (nous utiliserons tibble :: row_id_to_column
pour cela) et vous pourrez ensuite fusionner et gérer le conflit de colonnes avec sum
.
En utilisant les données de @ pierre-lapointe:
pie(unlist(res[1,])[-(1:2)])
Pour une ligne donnée (ici la première et la seule), vous pouvez obtenir votre camembert en le convertissant en vecteur avec désélectionner et supprimer les 2 premiers éléments non pertinents:
library(tibble) # devtools::install_github("moodymudskipper/safejoin") library(safejoin) res <- safe_inner_join(rowid_to_column(df1), rowid_to_column(df2), by = "rowid", conflict = sum) res # rowid ID a b c d e f g h # 1 1 471 18 17 28 29 44 8 37 14
Que diriez-vous simplement de
cbind (ID = sum (df1 [1], df2 [1]), df1 [-1], df2 [-1])
Dans le résultat souhaité, l'ID est additionné. Vous avez besoin d'au moins une colonne dans les deux tables pour fusionner.
@PierreLapointe: c'est pourquoi j'ai utilisé des noms pour faire le prénom des deux "ID". Était-ce mal?
Comme il s'agit d'une table 1-d, utilisez
c
au lieu decbind