0

I am working on SPSS data in R. TO modify/append data from different files, I had to convert the data into factor (as_factor(x, levels = "both") method). Now I need to write data back into an .SAV file but I am not able to convert my factor variables into labelled data. Please see below code snippet:-

x <- labelled(sample(5, 10, replace = TRUE), c(Bad = 1, Good = 5))
x1<-as_factor(x, levels = "both")
x2<-labelled(x1)

Error: `x` must be a numeric or a character vector

Is there a way to convert to spss data from factors.

kawsleo
  • 401
  • 2
  • 17

2 Answers2

1

This is a little messy, but it works for the small example you gave (not sure how it will go for your real data). The first problem is the factor levels being assigned by as_factor with the levels="both" option are pretty messy. You could convert to a numeric and then use labelled() from the haven package, but this may lead to some loss of information. Instead, what I've done is picked the levels="default" option and used the to_labelled() function from the labelled package. In this function I assigned labels for all of the factor levels (not just the two labels you started with), since otherwise these would get converted to NA.

Code:

library(haven)
library(labelled)

set.seed(617)
(x  = labelled(sample(5, 10, replace = TRUE), c(Bad = 1, Good = 5)))
(x1 = as_factor(x, levels="default"))
(x2 = to_labelled(x1, labels=c(Bad = 1, '2'=2, '3'=3, '4'=4, Good = 5)))

Output:

> set.seed(617)
> (x  = labelled(sample(5, 10, replace = TRUE), c(Bad = 1, Good = 5)))
<Labelled integer>
 [1] 1 4 1 1 1 1 3 3 3 4

Labels:
 value label
     1   Bad
     5  Good
> (x1 = as_factor(x, levels="default"))
 [1] Bad 4   Bad Bad Bad Bad 3   3   3   4  
Levels: Bad 3 4 Good
> (x2 = to_labelled(x1, labels=c(Bad = 1, '2'=2, '3'=3, '4'=4, Good = 5)))
<Labelled double>
 [1] 1 4 1 1 1 1 3 3 3 4

Labels:
 value label
     1   Bad
     2     2
     3     3
     4     4
     5  Good

This gets you back from a factor to labelled data. If you had to use the levels="both" option with as_factor(), you could do that, but you'd need to make sure you copy the factor levels back into the to_labelled() function appropriately.

Todd Burus
  • 823
  • 1
  • 5
  • 17
0

Yes, using to_labelled(x1):

library(tidyverse)
library(labelled)

> x <- labelled(sample(5, 10, replace = TRUE), c(Bad = 1, Good = 5))
> str(x)
'haven_labelled' int [1:10] 2 4 3 1 5 5 2 5 5 5
- attr(*, "labels")= Named num [1:2] 1 5
 ..- attr(*, "names")= chr [1:2] "Bad" "Good"

> x1 <- to_factor(x, levels = "labels")
> str(x1)
Factor w/ 5 levels "Bad","2","3",..: 2 4 3 1 5 5 2 5 5 5

> x2 <- to_labelled(x1)
> str(x2)
'haven_labelled' num [1:10] 2 4 3 1 5 5 2 5 5 5
- attr(*, "labels")= Named int [1:5] 1 2 3 4 5
 ..- attr(*, "names")= chr [1:5] "Bad" "2" "3" "4" ...
jared_mamrot
  • 6,036
  • 3
  • 11
  • 30
  • 1
    This leads to a possibly problematic loss of information. Try running with `set.seed(620)`. Using that seed, this method associates a label of "Bad" to a value of 4 instead of 5 since there is no level of 3 in the factor. – Todd Burus May 26 '20 at 05:04