user2543427
user2543427

Reputation: 133

If Statements in R, with a Data Frame

Suppose I have a data frame with several lines that look like:

        User    Lab    Score
         A       1       5
         A       2       6
         A       4       7
         B       1       3
         B       3       4
         C       2       5

Then, for lab 1, I want to divide the score by 5, for lab 2, I want to divide the score by 8, for lab 3, I want to divide the score by 7, and for lab 4 I want to divide the score by 9. How would I go about doing that?

Upvotes: 3

Views: 18714

Answers (3)

agstudy
agstudy

Reputation: 121568

Here a clean and generalisable solution using merge.

dat1  <- data.frame(Lab=c(1,2,3,4),
                    coef = c(1/5,1/8,1/7,1/9))
dt.m <- merge(dat,dat1,all.x=TRUE)
dt.m$coef[is.na(dt.m $coef)] <- 1   ## default value
dtt <- transform(dt.m,newScore=Score*coef)


   Lab User Score      coef  newScore
1   1    A     5 0.2000000 1.0000000
2   1    B     3 0.2000000 0.6000000
3   2    A     6 0.1250000 0.7500000
4   2    C     5 0.1250000 0.6250000
5   3    B     4 0.1428571 0.5714286
6   4    A     7 0.1111111 0.7777778

EDIT If you want to get the same order , structure as the original data :

dtt[order(dtt$User),c('User','Lab','Score','newScore')]
 User Lab Score  newScore
1    A   1     5 1.0000000
3    A   2     6 0.7500000
6    A   4     7 0.7777778
2    B   1     3 0.6000000
5    B   3     4 0.5714286
4    C   2     5 0.6250000

Upvotes: 2

A5C1D2H2I1M1N2O1R2T1
A5C1D2H2I1M1N2O1R2T1

Reputation: 193507

This might be pretty unorthodox, but could also be easier to read than a lot of ifelses. factor your "Lab" value, specify the divisor as the labels, and divide as normal. Assuming the data.frame is called "mydf":

within(mydf, {
  temp <- as.numeric(as.character(factor(Lab, levels=c(1, 2, 3, 4), 
                                         labels=c(5, 8, 7, 9))))
  Score <- Score/temp
  rm(temp)
})
#   User Lab     Score
# 1    A   1 1.0000000
# 2    A   2 0.7500000
# 3    A   4 0.7777778
# 4    B   1 0.6000000
# 5    B   3 0.5714286
# 6    C   2 0.6250000

Upvotes: 0

Hong Ooi
Hong Ooi

Reputation: 57686

For data transformation tasks like this, use ifelse, which is a vectorised form of selecting from different results based on a condition.

df$Score <- with(df, ifelse(Lab == 1, Score/5,
                     ifelse(Lab == 2, Score/8,
                     ifelse(Lab == 3, Score/7, Score/9))))

(This assumes you only have 4 Labs.)

Upvotes: 12

Related Questions