Derric Lewis
Derric Lewis

Reputation: 1243

How to change column values in a data frame?

I have a simple data frame column transformation which can be done using an if/else loop, but I was wondering if there was a better way to do this.

The initial data frame is,

 df <-data.frame(cbind(x=rep(10:15,3), y=0:8))
 df
    x y
1  10 0
2  11 1
3  12 2
4  13 3
5  14 4
6  15 5
7  10 6
8  11 7
9  12 8
10 13 0
11 14 1
12 15 2
13 10 3
14 11 4
15 12 5
16 13 6
17 14 7
18 15 8

what I need to do is replace the values in column 'y' such that

'0' gets replaced with '2',
'1' gets replaced with '2.2',
'2' gets replaced with '2.4',
...
...
'6' gets replaced with '3.2'
'7' gets replaced with '3.3'
'8' gets replaced with '10'

so that I end up with something like,

> df
    x    y
1  10  2.0
2  11  2.2
3  12  2.4
4  13  2.6
5  14  2.8
6  15  3.0
7  10  3.2
8  11  3.3
9  12 10.0
10 13  2.0
11 14  2.2
12 15  2.4
13 10  2.6
14 11  2.8
15 12  3.0
16 13  3.2
17 14  3.3
18 15 10.0

I have searched and found several proposals but couldnt get them to work. One of the attempts was something like,

> levels(factor(df$y)) <- c(2,2.2,2.4,2.6,2.8,3,3.2,3.3,10)

Error in levels(factor(df$y)) <- c(2, 2.2, 2.4, 2.6, 2.8, 3, 3.2, 3.3,  : 
  could not find function "factor<-"

But I get the error message shown above.

Can anyone help me with this?

Upvotes: 5

Views: 10567

Answers (2)

Ben Bolker
Ben Bolker

Reputation: 226801

How about:

mylevels <- c(2,2.2,2.4,2.6,2.8,3,3.2,3.3,10)
df$z <- as.numeric(as.character(factor(df$y,labels=mylevels)))

This also matches your desired outcome:

transform(df,z=ifelse(y==7,3.3,ifelse(y==8,10,2+y/5)))

Upvotes: 3

mnel
mnel

Reputation: 115475

Use the fact that y+1 is an index for the replacement

something like

replacement <- c(2,2.2,2.4,2.6,2.8,3,3.2,3.3,10)
df <- within(df, z <- replacement[y+1])

Or, using data.table for syntatic sugar and memory efficiency

library(data.table)
DT <- as.data.table(df)

DT[, z := replacement[y+1]]

Upvotes: 5

Related Questions