Mac
Mac

Reputation: 111

Function to change level of factored variable in R

The data frame is:

> head(td,3)
  CliC_1 CliC_2 CliC_3 Elev Gender PoliticalParty DegreeENV sq_d_shor
1      4      4      4    8      1              1         2  61.65299
2      1      4      1   29      1              3         2  63.60980
3      5      5      5   12      2              1         2 194.13505

the first three variables are factored.

> str(td$CliC_1)
 Factor w/ 5 levels "1","2","3","4",..: 4 1 5 3 5 5 4 5 5 4 ...
> str(td$CliC_2)
 Factor w/ 5 levels "1","2","3","4",..: 4 4 5 4 5 5 5 5 5 4 ...
> str(td$CliC_3)
 Factor w/ 5 levels "1","2","3","4",..: 4 1 5 3 5 5 5 5 4 3 ...

I want a function that will replace the levels ("1","2","3","4",..) to "Strongly Disagree", "Disagree", .... The function I wrote for this is:

asign_name<- function(data, var) {
        for (i in 1:nrow(data)) {
                if (var[i] == "1") {i <- "Strongly Disagree"}
                else if (var[i] == "2") {var[i]<- "Disagree"}
                else if (var[i] == "3") {var[i]<- "Neither"}
                else if (var[i] == "4") {var[i]<- "Agree"}
                else if (var[i] == "5") {var[i]<- "Strongly Agree"}

        }

        return (data)
}

But it is not changing the values:

> head(asign_name(td, td$CliC_1), 3)
  CliC_1 CliC_2 CliC_3 Elev Gender PoliticalParty DegreeENV sq_d_shor
1      4      4      4    8      1              1         2  61.65299
2      1      4      1   29      1              3         2  63.60980
3      5      5      5   12      2              1         2 194.13505

and I am getting warning message: Warning messages:

1: In `[<-.factor`(`*tmp*`, i, value = "Agree") :
  invalid factor level, NA generated

Upvotes: 1

Views: 80

Answers (2)

akrun
akrun

Reputation: 887851

You can create a key/value vector and use it for replacing the values in the 1st 3 columns.

 v1 <- setNames(c('Strongly Disagree', 'Disagree', 'Neither', 
             'Agree', 'Strongly Agree'),1:5)
 td[1:3] <- lapply(td[1:3], function(x) factor(v1[as.character(x)], levels=v1))
 td
 #            CliC_1         CliC_2            CliC_3 Elev Gender PoliticalParty
 #1             Agree          Agree             Agree    8      1              1
 #2 Strongly Disagree          Agree Strongly Disagree   29      1              3
 #3    Strongly Agree Strongly Agree    Strongly Agree   12      2              1
 #  DegreeENV sq_d_shor
 #1         2  61.65299
 #2         2  63.60980
 #3         2 194.13505

Upvotes: 2

MrFlick
MrFlick

Reputation: 206546

I'd probably use the levels<- command to replace factor levels. Here's an example

# define mapping
rr<-list(
  "Strongly Disagree"="1",
  "Disagree"="2",
  "Neither"="3",
  "Agree"="4",
  "Strongly Agree"="5"
)

# sample data
dd<-data.frame(
    a=factor(sample(1:5, 20, replace=T)),
    b=factor(sample(1:5, 20, replace=T))
)

# helper function
changelevels<-function(x) {
    levels(x)<-rr
      x
}

# column replacement
dd[,1:2]<-lapply(dd[,1:2], changelevels)

Upvotes: 3

Related Questions