Reputation: 1599
I've got this long, tidy dataframe that I've to make wide. Now usually I tackle this with the tidyr::spread()
function. But now I have to deal with multiple keys, values and naming conventions.
My example dataframe looks like this:
library(tidyverse)
df <- structure(list(Jaar = c(2014, 2014, 2015, 2015), Gemeente = c("Aa en Hunze",
"Aa en Hunze", "Aa en Hunze", "Aa en Hunze"), aantal_inw = c(25286L,
25286L, 25286L, 25286L), Categorie = c("Bedrijven", "Evenementen",
"Bedrijven", "Evenementen"), incidenten = c(6, 13, 2, 8), per_1000inw = c(0.2,
0.5, 0.1, 0.3)), class = c("tbl_df", "tbl", "data.frame"), .Names = c("Jaar",
"Gemeente", "aantal_inw", "Categorie", "incidenten", "per_1000inw"
), row.names = c(NA, -4L))
# A tibble: 4 x 6
Jaar Gemeente aantal_inw Categorie incidenten per_1000inw
<dbl> <chr> <int> <chr> <dbl> <dbl>
1 2014 Aa en Hunze 25286 Bedrijven 6 0.2
2 2014 Aa en Hunze 25286 Evenementen 13 0.5
3 2015 Aa en Hunze 25286 Bedrijven 2 0.1
4 2015 Aa en Hunze 25286 Evenementen 8 0.3
I would like to have all this data in one row where the Gemeente
(municipality) is the observation.
Desired outcome (as untidy as it may seem...) something like the following:
tibble::tribble(
~Gemeente, ~aantal_inw, ~Bedrijven_2014_incidenten, ~Bedrijven_2015_incidenten, ~Evenementen_2014_incidenten, ~Evenementen_2015_incidenten, ~Bedrijven_2014_per_1000inw, ~Bedrijven_2015_per_1000inw, ~Evenementen_2014_per_1000inw, ~Evenementen_2015_per_1000inw,
"Aa en Hunze", 25286L, 6L, 2L, 13L, 8L, 0.2, 0.1, 0.5, 0.3
)
# A tibble: 1 x 10
Gemeente aantal_inw Bedrijven_2014_i… Bedrijven_2015_i… Evenementen_2014… Evenementen_201… Bedrijven_2014_… Bedrijven_2015_… Evenementen_201… Evenementen_201…
<chr> <int> <int> <int> <int> <int> <dbl> <dbl> <dbl> <dbl>
1 Aa en Hunze 25286 6 2 13 8 0.2 0.1 0.5 0.3
All help much appreciated.
Upvotes: 0
Views: 341
Reputation: 73342
Or use data.table
.
library(data.table)
dt <- dcast(as.data.table(df), ... ~ Categorie + Jaar,
value.var=c("incidenten", "per_1000inw"))
Gives
> dt
Gemeente aantal_inw incidenten_Bedrijven_2014 incidenten_Bedrijven_2015
1: Aa en Hunze 25286 6 2
incidenten_Evenementen_2014 incidenten_Evenementen_2015
1: 13 8
per_1000inw_Bedrijven_2014 per_1000inw_Bedrijven_2015
1: 0.2 0.1
per_1000inw_Evenementen_2014 per_1000inw_Evenementen_2015
1: 0.5 0.3
Note: Use df <- as.data.frame(dt)
after to get again a data.frame
.
Upvotes: 0
Reputation: 876
untidy_df <- df %>%
gather(metric, value, 5:6) %>%
unite(combined_categories, c(Categorie, Jaar, metric)) %>%
spread(combined_categories, value)
Upvotes: 1
Reputation: 16121
library(tidyverse)
df %>%
gather(v1, v2, -Jaar, -Gemeente, -aantal_inw, -Categorie) %>%
unite(v3, Categorie, Jaar, v1) %>%
spread(v3, v2) %>%
data.frame()
# Gemeente aantal_inw Bedrijven_2014_incidenten Bedrijven_2014_per_1000inw Bedrijven_2015_incidenten Bedrijven_2015_per_1000inw
# 1 Aa en Hunze 25286 6 0.2 2 0.1
# Evenementen_2014_incidenten Evenementen_2014_per_1000inw Evenementen_2015_incidenten Evenementen_2015_per_1000inw
# 1 13 0.5 8 0.3
Note that I'm using data.frame()
in the end only for visualisation purposes (i.e. to print the whole columns names for you to check it's OK)
Upvotes: 3