2

Say I have a data frame with the contents:

Trial Person Time
1     John   1.2
2     John   1.3
3     John   1.1
1     Bill   2.3
2     Bill   2.5
3     Bill   2.7

and another data frame with the contents:

Person Offset
John   0.5
Bill   1.0

and I want to modify the original frame based on the appropriate value from the second. I could do this easily in any other language or in SQL, and I'm sure I could manage using for loops and what, but with everything else I see in R, I'm guessing it has special syntax to do this as a one-liner. So, if so, how? And if not, could you show how it could be done using loops. I haven't actually got around to learning looping in R yet since it has amazing things to simply extract and manipulate whatever values.

For reference, the output would:

Trial Person Time
1     John   0.7
2     John   0.8
3     John   0.6
1     Bill   1.3
2     Bill   1.5
3     Bill   1.7 
Kara
  • 6,115
  • 16
  • 50
  • 57
Reverend Gonzo
  • 39,701
  • 6
  • 59
  • 77
  • you could have used a more specific title.. – dalloliogm Feb 11 '10 at 12:09
  • @dalloliogm Feel free to throw a recommendation....I got the answer I needed within ten minutes – Reverend Gonzo Feb 11 '10 at 13:53
  • yes but because the title was so general that people looked at it just to understand better what was it. So you have taken away the attention from other questions which maybe were better written, and that's unfair. A good title should be so that one can have an idea of what you are going to ask just by reading it. Anyway, peace, you haven't done anything too terrible, it's ok. – dalloliogm Feb 11 '10 at 15:08
  • I'll change the title if you have a better way of describing it ... I just didn't know how I could describe my problem in a way that explained it perfectly. – Reverend Gonzo Feb 11 '10 at 15:20
  • Take a look at this SO question http://stackoverflow.com/questions/1299871/how-to-join-data-frames-in-r-inner-outer-left-right to figure out how to use merge. – Eduardo Leoni Feb 11 '10 at 17:29

2 Answers2

5

There are many possibilities. Here is a simple one using merge() and a simple column-wise subtraction in the enlarged data.frame:

R> DF1 <- data.frame(trial=rep(1:3,2), \
                     Person=rep(c("John","Bill"), each=3), \
                     Time=c(1.2,1.3,1.1,2.3,2.5,2.7))
R> DF2 <- data.frame(Person=c("John","Bill"), Offset=c(0.5,1.0))
R> DF <- merge(DF1, DF2)
R> DF
  Person trial Time Offset
1   Bill     1  2.3    1.0
2   Bill     2  2.5    1.0
3   Bill     3  2.7    1.0
4   John     1  1.2    0.5
5   John     2  1.3    0.5
6   John     3  1.1    0.5
R> DF$NewTime <- DF$Time - DF$Offset
R> DF
  Person trial Time Offset NewTime
1   Bill     1  2.3    1.0     1.3
2   Bill     2  2.5    1.0     1.5
3   Bill     3  2.7    1.0     1.7
4   John     1  1.2    0.5     0.7
5   John     2  1.3    0.5     0.8
6   John     3  1.1    0.5     0.6
R> 
Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • Ha! I just figured out a one-liner using a for loop, but this is even more beautiful. I didn't realize you could merge two frames, and it'll figure out where they go based on the column names. – Reverend Gonzo Feb 11 '10 at 01:38
1

One liner:

transform(merge(d1,d2), Time=Time - Offset, Offset=NULL)