This is a tricky one. So, I will show stepwise what I have tried.
1. Reshaping without label<-()
In a first attempt, I resorted to data.table
which I am more acquainted.
library(data.table) # for melt() and dcast()
library(magrittr) # for piping %>%
df1 %>%
setDT() %>%
melt(measure.vars = patterns("^20"), variable.name = "Year") %>%
dcast(... ~ Varcode + Variables)
Country Ccode Year H_Happiness P_Power
1: France FR 2000 1872 1213
2: France FR 2001 2345 1234
3: UK UK 2000 2234 1726
4: UK UK 2001 9082 6433
Now, the column headers of the value vars contain Varcode
and Variables
. I have tried this because I was unsure what the OP is aiming to achieve with using Hmisc::label()
.
2. Reshaping with label<-()
df2 <- df1 %>%
setDT() %>%
melt(measure.vars = patterns("^20"), variable.name = "Year") %>%
dcast(Year + Country + Ccode ~ Varcode)
Year Country Ccode H P
1: 2000 France FR 1872 1213
2: 2000 UK UK 2234 1726
3: 2001 France FR 2345 1234
4: 2001 UK UK 9082 6433
Now, we have to add lables to columns H
and P
.
# create list of labels
Lbl <- df1[, .(Variables, Varcode)] %>% unique()
Lbl
Variables Varcode
1: Power P
2: Happiness H
# set labels
for (i in seq_len(nrow(Lbl))) {
Hmisc::label(df2[[Lbl$Varcode[i]]]) <- Lbl$Variables[i]
}
str(df2)
Classes ‘data.table’ and 'data.frame': 4 obs. of 5 variables:
$ Year : Factor w/ 2 levels "2000","2001": 1 1 2 2
$ Country: chr "France" "UK" "France" "UK"
$ Ccode : chr "FR" "UK" "FR" "UK"
$ H : 'labelled' int 1872 2234 2345 9082
..- attr(*, "label")= chr "Happiness"
$ P : 'labelled' int 1213 1726 1234 6433
..- attr(*, "label")= chr "Power"
- attr(*, ".internal.selfref")=<externalptr>
- attr(*, "sorted")= chr "Year" "Country" "Ccode"
Now, both columns H
and P
have been labeled accordingly.
3. Completing OP's approach
library(dplyr)
library(tidyr)
df2 <- df1 %>%
select(-Variables) %>%
gather(Year, val,`2000`:`2001`) %>%
spread(Varcode, val)
df2
Country Ccode Year H P
1 France FR 2000 1872 1213
2 France FR 2001 2345 1234
3 UK UK 2000 2234 1726
4 UK UK 2001 9082 6433
Note that the calls to unite()
and separate()
have been skipped as they are not needed to reproduce the expected result.
Lbl <- df1 %>%
distinct(Varcode, Variables)
for (i in seq_len(nrow(Lbl))) {
Hmisc::label(df2[[Lbl$Varcode[i]]]) <- Lbl$Variables[i]
}
str(df2)
'data.frame': 4 obs. of 5 variables:
$ Country: chr "France" "France" "UK" "UK"
$ Ccode : chr "FR" "FR" "UK" "UK"
$ Year : chr "2000" "2001" "2000" "2001"
$ H : 'labelled' int 1872 2345 2234 9082
..- attr(*, "label")= chr "Happiness"
$ P : 'labelled' int 1213 1234 1726 6433
..- attr(*, "label")= chr "Power"
Data
df1 <- data.table::fread(
"i Variables Varcode Country Ccode 2000 2001
1 Power P France FR 1213 1234
2 Happiness H France FR 1872 2345
3 Power P UK UK 1726 6433
4 Happiness H UK UK 2234 9082
", drop = 1L, data.table = FALSE)