J'ai un dataframe R avec ce type de structure (exemple factice):
spread_df_C <- spread(df, B, C) aggregated_df_C <- aggregate(spread_df$a, list(spread_df$A), mean) spread_df_D <- spread(df, B, D) aggregated_df_D <- aggregate(spread_df$a, list(spread_df$A), mean) new_df <- merge(aggregated_df_C, aggregated_df_D, by=c("A", "A")
"A", "B", "C" et "D" sont des en-têtes de colonne.
/ p>
Je veux remodeler ce dataframe de sorte que j'obtienne la moyenne (moyenne) de "C" et "D" par chaque niveau de "A" et "B".
Donc le produit final que je veux serait:
new_df A BaC BbC BaD BbD 1 4 2 4 8 2 5 4 6 3
J'ai réussi à le faire d'une manière très grossière:
df A B C D 1 a 3 5 1 a 5 3 1 b 2 8 2 a 4 7 2 a 6 5 2 b 4 3 ...
Cela me donnerait finalement le produit final, mais je calcule laborieusement la moyenne pour chacun des niveaux. Je dois faire cela pour plusieurs niveaux, et il doit y avoir une manière plus élégante de l'exécuter.
Experts, veuillez aider
3 Réponses :
Une option utilisant le package reshape2
.
library(reshape2) dcast(melt(dat, measure.vars = c("C", "D")), A ~ B + variable, fun.aggregate = mean) # A a_C a_D b_C b_D #1 1 4 4 2 8 #2 2 5 6 4 3
La première étape consiste à fondre
les colonnes C
et D
, puis reconstituer la trame de données résultante au format large.
Avec tidyverse
, vous pouvez faire:
df %>% gather(var, val, -c(1:2)) %>% group_by_at(1:3) %>% summarise(val = mean(val)) %>% ungroup() %>% mutate(var = paste(var, B, sep = "_")) %>% select(-2) %>% spread(var, val) A C_a C_b D_a D_b <int> <dbl> <dbl> <dbl> <dbl> 1 1 4 2 4 8 2 2 5 4 6 3
Considérez le remodelage
de la base R après l'agrégation et le changement de nom de colonne avant / après la période:
agg <- aggregate(. ~ A + B, df, mean) rdf <- reshape(agg, idvar = "A", timevar = "B", direction = "wide") names(rdf)[-1] <- paste0("B", substr(names(rdf)[-1], 3, 3), substr(names(rdf)[-1], 1, 1)) rdf # A BaC BaD BbC BbD # 1 1 4 4 2 8 # 2 2 5 6 4 3