I have the table below scraped from the web, it has 2 grouped columns in header.
structure(list(Provenance = c(NA, "Bourgs", "Rurales"), `Mari Vivant` = c("OUI",
"81", "120"), ...3 = c("NON", "10", "12"), ...4 = c("Pas spécifié",
"2", "5"), `Type d’union` = c("Mariée", "50", "48"), ...6 = c("Mariée après union libre",
"7", "18"), ...7 = c("Union libre et mariage", "5", "4"), ...8 = c("Union libre",
"31", "67")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-3L))
I would like to tidy the data. How to do that in tidyverse or with data.table in R ?
I would expect a tibble with all possible combinations of the variables like that (first 10 rows)
A tibble: 27 x 8
Provenance `Mari Vivant` `Type d’union` ...3 ...4 ...6 ...7
<chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 Bourgs NON Mariée NA NA NA NA
2 Bourgs NON Mariée après ~ NA NA NA NA
3 Bourgs NON Union libre NA NA NA NA
4 Bourgs NON Union libre e~ NA NA NA NA
5 Bourgs OUI Mariée NA NA NA NA
6 Bourgs OUI Mariée après ~ NA NA NA NA
7 Bourgs OUI Union libre NA NA NA NA
8 Bourgs OUI Union libre e~ NA NA NA NA
9 Bourgs Pas spécifié Mariée NA NA NA NA
10 Bourgs Pas spécifié Mariée après ~ NA NA NA NA
I did try:
df.all <- tidyr::complete(bouch, Provenance= c("Bourgs", "Rurales"), `Mari Vivant`= c("OUI", "NON","Pas spécifié"),
`Type d’union`= c("Mariée", "Mariée après union libre","Union libre et mariage", "Union libre"),
fill = list(value = NA))
and getting a tibble who has the values at the tail as (tail shown below:)
Provenance `Mari Vivant` `Type d’union` ...3 ...4 ...6 ...7
<chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 Rurales Pas spécifié Mariée après u~ NA NA NA NA
2 Rurales Pas spécifié Union libre NA NA NA NA
3 Rurales Pas spécifié Union libre et~ NA NA NA NA
4 NA OUI Mariée NON Pas ~ Mari~ Unio~
5 Bourgs 81 50 10 2 7 5
6 Rurales 120 48 12 5 18 4
# ... with 1 more variable: ...8 <chr>
Not exactly what I wanted, i.e line 4.
I tried the grid_expand approach and it seems to be on the right track except I would also like to have a value column like this instead of NA'S where values exist.
Provenance Mari Vivant Type d’union value ..4 ..6
1 Bourgs OUI Mariée 50 NA NA
2 Rurales OUI Mariée 48 NA NA
3 Bourgs NON Mariée NA NA NA
4 Rurales NON Mariée NA NA NA
5 Bourgs Pas spécifié Mariée NA NA NA
6 Rurales Pas spécifié Mariée NA NA NA
7 Bourgs OUI Mariée après union libre 7 NA NA
8 Rurales OUI Mariée après union libre 18 NA NA
9 Bourgs NON Mariée après union libre NA NA NA
10 Rurales NON Mariée après union libre NA NA NA
11 Bourgs Pas spécifié Mariée après union libre NA NA NA
12 Rurales Pas spécifié Mariée après union libre NA NA NA
13 Bourgs OUI Union libre et mariage 5 NA NA
14 Rurales OUI Union libre et mariage 4 NA NA
15 Bourgs NON Union libre et mariage NA NA NA
16 Rurales NON Union libre et mariage NA NA NA
17 Bourgs Pas spécifié Union libre et mariage NA NA NA
18 Rurales Pas spécifié Union libre et mariage NA NA NA
19 Bourgs OUI Union libre 31 NA NA
20 Rurales OUI Union libre 67 NA NA
21 Bourgs NON Union libre 10 NA NA
22 Rurales NON Union libre 12 NA NA
23 Bourgs Pas spécifié Union libre 2 NA NA
24 Rurales Pas spécifié Union libre 5 NA NA
Different from Tidyr
option, you could use expand.grid
to generate the data frame:
df <- expand.grid(Provenance = c("Bourgs", "Rurales"),
`Mari Vivant` =c("OUI","NON", "Pas spécifié"),
`Type d’union` =c("Mariée", "Mariée après union libre", "Union libre et mariage", "Union libre"))
'data.frame': 24 obs. of 3 variables:
Provenance Mari Vivant Type d’union
1 Bourgs OUI Mariée
2 Rurales OUI Mariée
3 Bourgs NON Mariée
4 Rurales NON Mariée
5 Bourgs Pas spécifié Mariée
And add the NA columns:
New_cols = c("..3", "..4", "..6", "..7", "..8")
df[New_cols] <- NA
'data.frame': 24 obs. of 8 variables:
Provenance Mari Vivant Type d’union ..3 ..4 ..6 ..7 ..8
1 Bourgs OUI Mariée NA NA NA NA NA
2 Rurales OUI Mariée NA NA NA NA NA
3 Bourgs NON Mariée NA NA NA NA NA
4 Rurales NON Mariée NA NA NA NA NA
5 Bourgs Pas spécifié Mariée NA NA NA NA NA
Data:
structure(list(Provenance = c(NA, "Bourgs", "Rurales"), `Mari Vivant` = c("OUI",
"81", "120"), ...3 = c("NON", "10", "12"), ...4 = c("Pas spécifié",
"2", "5"), `Type d’union` = c("Mariée", "50", "48"), ...6 = c("Mariée après union libre",
"7", "18"), ...7 = c("Union libre et mariage", "5", "4"), ...8 = c("Union libre",
"31", "67")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-3L))
You could generate 2 data frames with each your values of interest:
Mari = df[,c(1:4)]
names(Mari) = c(names(Mari)[1], as.character(as.vector(Mari[1,]))[-1])
Mari = Mari %>% filter(!is.na(Provenance)) %>% pivot_longer(!Provenance, names_to = "Mari-vivant", values_to = "count")
# A tibble: 6 x 3
Provenance `Mari-vivant` count
<chr> <chr> <chr>
1 Bourgs OUI 81
2 Bourgs NON 10
3 Bourgs Pas spécifié 2
4 Rurales OUI 120
5 Rurales NON 12
6 Rurales Pas spécifié 5
And the second one:
Type = df[,c(1, 5:8)]
names(Type)= c(names(Type)[1], as.character(as.vector(Type[1,]))[-1])
Type = Type %>% filter(!is.na(Provenance)) %>% pivot_longer(!Provenance, names_to = "Type-d-union", values_to = "count2")
# A tibble: 8 x 3
Provenance `Type-d-union` count2
<chr> <chr> <chr>
1 Bourgs Mariée 50
2 Bourgs Mariée après union libre 7
3 Bourgs Union libre et mariage 5
4 Bourgs Union libre 31
5 Rurales Mariée 48
6 Rurales Mariée après union libre 18
7 Rurales Union libre et mariage 4
8 Rurales Union libre 67
Finally you can merge the 2 data frames into a single one if you want everything in one place:
Type %>% left_join(Mari, by = "Provenance")
A tibble: 24 x 5
Provenance `Type-d-union` count2 `Mari-vivant` count
<chr> <chr> <chr> <chr> <chr>
1 Bourgs Mariée 50 OUI 81
2 Bourgs Mariée 50 NON 10
3 Bourgs Mariée 50 Pas spécifié 2
4 Bourgs Mariée après union libre 7 OUI 81
5 Bourgs Mariée après union libre 7 NON 10
6 Bourgs Mariée après union libre 7 Pas spécifié 2
7 Bourgs Union libre et mariage 5 OUI 81
8 Bourgs Union libre et mariage 5 NON 10
9 Bourgs Union libre et mariage 5 Pas spécifié 2
10 Bourgs Union libre 31 OUI 81
# ... with 14 more rows