0

I would like to use the column Variables of a dataframe:

  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

to assign labels to the column names (from variable P onwards) of another (reshaped) dataframe:

  Year      Country Ccode P(label=Power) H(label=Happiness)
1 2000      France  FR    1213           1872  
2 2001      France  FR    1234           2345
3 2000      UK      UK    1726           2234
4 2001      UK      UK    6433           9082

I had the following in mind:

Before reshaping

library(Hmisc)
LabelList <- as.data.frame(df1$Varcode)
LabelList <- as.character(LabelList) #(EDIT)

Reshaping

df2 %>% 
  select(-Variables) %>% 
  gather(Year, val,`2000`:`2001`) %>% 
  unite(Country_Ccode, Country, Ccode, sep = "_") %>% 
  spread(Varcode, val) %>% 
  separate(Country_Ccode, c("Country", "Ccode"), sep = "_")

After reshaping (EDIT:the label function only allows a vector of 1)

for(i in LabelList){
label(df2[,i]) <- LabelList[i]

But then I get the following error:

Error in `[.data.frame`(List, i) : undefined columns selected
Error : Unsupported index type: factor

After as.character(LabelList) the error becomes:

Error : Column `c(1, 2, 3, 4, 5, 6, .., )

Any ideas?

Tom
  • 2,173
  • 1
  • 17
  • 44
  • one of your variables is a factor when the function is expecting a string (most likely). do an `str(yourDF)` and figure out which column is a factor and change it to a character. – JD Long Aug 03 '18 at 14:48

1 Answers1

1

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)
Community
  • 1
  • 1
Uwe
  • 41,420
  • 11
  • 90
  • 134
  • Thank you for making my week on Monday morning. That went in one go.. Thank you so much for your effort! – Tom Aug 06 '18 at 07:42