Search code examples
rr-haven

R - Loss labels when I ordered a data frame after using read_sav from haven package


I use the read_sav function from haven package to import an SPSS file. Therefore I have column names and associate labels (class labelled).

I lost the labels when I ordered the data frame. I can avoid the problem with a conversion in factor before order but is it a bug or a normal behavior ?

Here is a simple example.

DataForExample <- structure(list(CollectorNm = structure(c("Email Invitation 8", "Email Invitation 8", "Email Invitation 8", "Email Invitation 8", "Email Invitation 8", "Email Invitation 8"), label = "CollectorNm"), q0001 = structure(c(1, 1, 1, 1, 1, 1), label = "Avez-vous déjà suivi la formation Atlas-Vente des 18 et 19 octobre ?", class = "labelled", labels = structure(c(1, 2), .Names = c("Oui, j'ai bien suivi cette formation.", "Non, je n'y ai pas participé." ))), q0002_0001 = structure(c(3, 3, 3, 2, 3, 3), label = "La formation dans son ensemble", class = "labelled", labels = structure(c(1, 2, 3, 4), .Names = c("pas du tout satisfait", "plutôt pas satisfait", "plutôt satisfait", "très satisfait")))), .Names = c("CollectorNm", "q0001", "q0002_0001"), class = c("tbl_df", "tbl", "data.frame" ), row.names = c(NA, -6L))

View(DataForExample) # OK Toto <- DataForExample[order(DataForExample$q0001_0001),] View(Toto) # NOK : the labels disappeared

Thanks


Solution

  • You need to load package with support for subsetting operations for class labelled. It is better to load it after the haven. There are at least two packages with such support: Hmisc and expss. Disclaimer: I am an author of the expss package.

    UPDATE. Fix labelled class.

    It seems that haven doesn't set labelled class for all variables with labels. So we need to fix it:

    library(expss)
    
    for(each in colnames(DataForExample)){
        if(!("labelled" %in% class(DataForExample[[each]])) && 
           (!is.null(var_lab(DataForExample[[each]])) ||
            !is.null(val_lab(DataForExample[[each]]))
           )) {
            class(DataForExample[[each]]) = union("labelled", class(DataForExample[[each]]))
        }
    }
    
    View(DataForExample) # OK
    Toto <- DataForExample[order(DataForExample$q0001),]
    View(Toto) # OK