tidyverse / haven

Read SPSS, Stata and SAS files from R
https://haven.tidyverse.org
Other
424 stars 117 forks source link

'write_sav' does not save value labels of labelled class, but only haven_labelled class? #666

Closed khanhhtt closed 2 years ago

khanhhtt commented 2 years ago

Hi team, I have read the information on another thread (#21) that the function "write_sav" will work for factors or labelled class. But when I tested on the data with labelled class, the datafile output is missing value label. When I change the class to _havenlabelled, the the value label is written successfully on the output file.

Please see below my test. I also enclose the output files for your reference. Thank you in advance for looking into this.

data(mtcars)
mtcars = modify(mtcars,{
  var_lab(mpg) = "Miles/(US) gallon"
  var_lab(cyl) = "Number of cylinders"
  var_lab(disp) = "Displacement (cu.in.)"
  var_lab(hp) = "Gross horsepower"
  var_lab(drat) = "Rear axle ratio"
  var_lab(wt) = "Weight (lb/1000)"
  var_lab(qsec) = "1/4 mile time"
  var_lab(vs) = "Engine"
  val_lab(vs) = c("V-engine" = 0, 
                  "Straight engine" = 1) 
  var_lab(am) = "Transmission"
  val_lab(am) = c(automatic = 0, 
                  manual=1)
  var_lab(gear) = "Number of forward gears"
  var_lab(carb) = "Number of carburetors"
})

vt(mtcars)

# This output data does not contain any value label
write_sav(mtcars, "data1.sav")

![image](https://user-images.githubusercontent.com/93310387/158334969-3968dbe1-2929-4da7-aeaa-a4ca60a74b2a.png)

# Convert variable "vs" to haven_labelled then its value labels appear in the output datafile.
class(mtcars$vs) = "haven_labelled"
vt(mtcars)
write_sav(mtcars, "data2.sav")

![image](https://user-images.githubusercontent.com/93310387/158335183-d083c510-b457-46e0-adf3-133fbab8a208.png)

TEST.zip

gorcha commented 2 years ago

Hi @khanhhtt, the correct class for labelled vectors in haven is haven_labelled. Some other packages (e.g. expss, Hmisc) have a labelled class. The haven class was originally called labelled, but this was changed to haven_labelled in version 2.0.0 to avoid conflicts with other packages.

It looks like the sample code above is coming from expss - expss uses a different class to store value and variable labels so it doesn't play nicely with haven. The correct way to create a labelled vectors in haven is to use the labelled() function. For easier manipulation of attributes the labelled package provides helper functions (for e.g. val_labels(), var_labels()) similar to the functions from expss used in your example above that are built to work with haven.