0

I would like to get the max value and assign the colnames back to the data frame. I tried to loop it. Any suggestions? Thanks

new<-data.frame(id=seq(1:5),att1=rnorm(5,1),att2=rnorm(5,1),att3=rnorm(5,1))
for (i in 1:nrow(new))
new$type<-names(which.max(new[i,2:4]))

id       att1       att2      att3 type
1 -1.1735401  0.1269600 0.6178781 att3
2  1.9650696 -0.2129732 0.5030030 att3
3 -0.0901813  4.3937726 1.1886939 att3
4  0.1719326  1.9478824 2.2497336 att3
5  2.1359702  2.3347643 2.6607773 att3
chee.work.stuff
  • 326
  • 2
  • 14

2 Answers2

3

Try apply;

new$type <- names(new)[apply(new[-1], 1, which.max) + 1]

  id        att1      att2       att3 type
1  1  1.77432474 0.3306480  0.9693518 att1
2  2 -0.00585121 0.2115700  0.6579220 att3
3  3  0.23611749 0.7180739  1.9325201 att3
4  4  0.43156117 0.9980831 -1.2525760 att2
5  5  2.10921757 1.3001635  0.4259629 att1
Sven Hohenstein
  • 80,497
  • 17
  • 145
  • 168
2
names(new)[2:4][max.col(new[, 2:4])]

As a general rule, don't use apply with data frames. It will turn the input df into a matrix, which, if you have any character or factor columns, will result in a character matrix.

Hong Ooi
  • 56,353
  • 13
  • 134
  • 187
  • Yes, `apply`, will transform the data frame into a matrix. But the same applies to `max.col`. Have a look at the code, particularly the following line: `m <- as.matrix(m)`. – Sven Hohenstein Jan 10 '14 at 09:14
  • @SvenHohenstein I did say "as a general rule". In this case all the necessary columns are numeric so it's safe to use `apply` (after you do proper subsetting). But often you want to do a row-wise operation on a data frame that involves both numeric and character/factor columns, and `apply` won't help then. – Hong Ooi Jan 10 '14 at 09:23
  • hmmm.. what if I want to return more than one names? if there are two columns share same max? – chee.work.stuff Jan 10 '14 at 09:35