I have a roster of employees, and I need to know at what department they are in most often. It is trivial to tabulate employee ID against department name, but it is trickier to return the department name, rather than the number of roster counts, from the frequency table. A simple example below (column names = departments, row names = employee ids).
DF <- matrix(sample(1:9,9),ncol=3,nrow=3)
DF <- as.data.frame.matrix(DF)
> DF
V1 V2 V3
1 2 7 9
2 8 3 6
3 1 5 4
Now how do I get
> DF2
RE
1 V3
2 V1
3 V2
One solution could be to reshape the date from wide to long putting all the departments in one column and counts in another, group by the employer id (in this case, the row number), and then filter to the department(s) with the max value. There are a couple of options for handling ties with this approach too.
A simple
for
loop can also be handy:One option using your data (for future reference, use
set.seed()
to make examples usingsample
reproducible):A faster solution than using
apply
might bemax.col
:...where
ties.method
can be any of"random"
"first"
or"last"
This of course causes issues if you happen to have two columns which are equal to the maximum. I'm not sure what you want to do in that instance as you will have more than one result for some rows. E.g.:
A
dplyr
solution:Idea:
Code:
Result:
This approach can be easily extended to get the top
n
columns. Example forn=2
:Result:
Based on the above suggestions, the following
data.table
solution worked very fast for me:And also comes with the advantage that can always specify what columns
.SD
should consider by mentioning them in.SDcols
:If you're interested in a
data.table
solution, here's one. It's a bit tricky since you prefer to get the id for the first maximum. It's much easier if you'd rather want the last maximum. Nevertheless, it's not that complicated and it's fast!Here I've generated data of your dimensions (26746 * 18).
Data
data.table
answer:Benchmarking:
It's about 11 times faster on data of these dimensions, and
data.table
scales pretty well too.Edit: if any of the max ids is okay, then: