wmsmith
wmsmith

Reputation: 542

Compute values relative to specific factor in R data frame

I have a data frame in R of the following form:

        BC solvopt istrng tSolv      EPB
    1   10       1      0  0.10 -78.1450
    2   10       1      1  0.15 -78.7174
    3   10       1     10  0.14 -78.7175
    4   10       1    100  0.12 -78.7184
    5   10       1   1000  0.09 -78.7232
    6   10       1      2  0.15 -78.7175
    7   10       1     20  0.14 -78.7176
    8   10       1    200  0.12 -78.7192
    30  10       2      0  0.10 -78.1450
    31  10       2      1  0.11 -78.7174
    32  10       2     10  0.11 -78.7175
    33  10       2    100  0.10 -78.7184
    34  10       2   1000  0.13 -78.7232
    35  10       2      2  0.11 -78.7174
    36  10       2     20  0.10 -78.7176
    37  10       2    200  0.10 -78.7192
    59  10       3      0  0.16 -78.1450
    60  10       3      1  0.23 -78.7174
    61  10       3     10  0.21 -78.7175
    62  10       3    100  0.19 -78.7184
    63  10       3   1000  0.17 -78.7232
    64  10       3      2  0.22 -78.7175
    65  10       3     20  0.21 -78.7176
    66  10       3    200  0.18 -78.7192
    88  10       4      0  0.44 -78.1450
    89  10       4      1 14.48 -78.7162
    90  10       4     10 12.27 -78.7175
    91  10       4    100  1.23 -78.7184
    92  10       4   1000  0.44 -78.7232
    93  10       4      2 14.52 -78.7172
    94  10       4     20  6.16 -78.7176
    95  10       4    200  0.62 -78.7192

I want to add a column to this frame which shows the relative error in the EPB for each value of BC and istrng relative to solvopt=3.

For example, to compute the relative difference in EPB at each row I would subtract the EPB value of the corresponding row with the same value of BC and istrng but with solvopt=3.

Is there an easy way to do this short of splitting this into multiple data frames (for each solvopt) and then remunging it together?

The end goal is to generate plots of relative error vs istrng for each value of BC using qplot.

Upvotes: 2

Views: 85

Answers (2)

akrun
akrun

Reputation: 887098

A similar option with data.table

library(data.table)
 res <- setkey(setDT(dat), BC,istrng)[dat[solvopt==3, c(1,3,5),
                 with=FALSE]][, diff:= EPB- i.EPB][]

Upvotes: 1

thelatemail
thelatemail

Reputation: 93813

If you merge the subset where solvopt==3 against the main data on both BC and istrong, and subtract the difference, you should get the result you want, e.g.:

newdat <- merge(dat,dat[dat$solvopt==3,c("BC","istrng","EPB")], by=c("BC","istrng"))
newdat$diff <- with(newdat, EPB.x - EPB.y)

...or do it all in one fell swoop using match and interaction:

dat$diff <- dat$EPB - dat[dat$solvopt==3,"EPB"][match(
  with(dat,                  interaction(BC,istrng) ),
  with(dat[dat$solvopt==3,], interaction(BC,istrng) ) 
)]

Upvotes: 1

Related Questions