Nick
Nick

Reputation: 145

ave and which.max in R

I have a question about getting index values using which.max() in the ave function. I start with the following data.frame:

df <- data.frame(t_subjNum = c(1,1,1,1,1,1,1,2,2,2,2,2,2,2,2),
                 t_trialNum= c(1,1,1,2,2,2,2,1,1,1,1,2,2,2,2),
                 perpdist =  c(50,51,49,2,3,4,2,1,2,2,1,4,5,2,2),
                 angdiff =   c(60,61,60,-80,-81,-82,-81,40,41,42,41,61,60,61,62))

I would like to pull the angdiff for the maximum absolute perpdist of each t_subjNum by t_trialNum interaction. So, I made a formula like this:

df$maxangleINCORRECT   <- ave(df$perpdist, 
                       interaction(df$t_subjNum, df$t_trialNum), 
                       FUN = function(x) df$angdiff[which.max(abs(x))])

It results in the wrong angdiff values. It creates an index for the subset of observations in the t_subjNum and t_trialNum interaction (e.g., 3 rather than 6 for subjNum = 1 and trialNum = 2). Any ideas on how to fix the indexing here?

Just to illustrate the incorrect result and the desired correct result.

   t_subjNum t_trialNum perpdist angdiff maxangleINCORRECT maxangleCORRECT
1          1          1       50      60                61              61
2          1          1       51      61                61              61
3          1          1       49      60                61              61
4          1          2        2     -80                60             -82
5          1          2        3     -81                60             -82
6          1          2        4     -82                60             -82
7          1          2        2     -81                60             -82
8          2          1        1      40                61              41
9          2          1        2      41                61              41
10         2          1        2      42                61              41
11         2          1        1      41                61              41
12         2          2        4      61                61              60
13         2          2        5      60                61              60
14         2          2        2      61                61              60
15         2          2        2      62                61              60

Upvotes: 1

Views: 284

Answers (1)

Heroka
Heroka

Reputation: 13149

I tried tinkering with ave, but found it quite complicated as it takes one numeric as argument, so as you already found which.max gives you trouble. You could consider using data.table. I realize the output of this doesn't match maxAngleCORRECT, but I think that's something to do with ties (with t_subjNum==2 and t_trialNum==2, max abs(perpdist) is 5, leadong to an anglediff of 60.

library(data.table)
setDT(df)[,maxangle:=angdiff[which.max(abs(perpdist))],by=.(t_subjNum,t_trialNum)]

Upvotes: 5

Related Questions