Reputation: 1243
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
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
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