Reputation: 445
I have some data containing numeric columns:
df <- data.frame(v1 = c(0,1,2,3,4,5,6,7,8), v2 = c(5,6,3,21,24,7,8,9,6), v3 = c(23,5,24,87,6,32,5,48,6),v4 = c(2,32,6,58,5,21,4,5,87), v5 = c(5,23,65,86,4,12,115,5,24))
I need to create three new columns containing the first, second and third largest value per row. So the desired output would be this:
v1 v2 v3 v4 v5 first second third
1 0 5 23 2 4 23 5 4
2 1 6 5 32 23 32 23 6
3 2 3 24 6 65 65 24 6
4 3 21 87 58 87 87 86 58
5 4 24 6 5 4 24 6 5
6 5 7 32 21 12 32 21 12
7 6 8 5 4 115 115 8 6
8 7 9 48 5 5 48 9 5
9 8 6 6 87 24 87 24 8
Any easy way to do this? I can get the max value with which.max, it's just finding the second and third max that's confusing me
Upvotes: 0
Views: 1040
Reputation:
You can use
# add the columns
df <- cbind.data.frame(df, t(apply(df, 1, function(row_i){
sort(row_i, decreasing = TRUE)[1:3]})))
# name the columns
names(df)[(ncol(df)-2):ncol(df)] <- c("first", "second", "third")
# see results
df
v1 v2 v3 v4 v5 first second third
1 0 5 23 2 4 23 5 4
2 1 6 5 32 23 32 23 6
3 2 3 24 6 65 65 24 6
4 3 21 87 58 87 87 86 58
5 4 24 6 5 4 24 6 5
6 5 7 32 21 12 32 21 12
7 6 8 5 4 115 115 8 6
8 7 9 48 5 5 48 9 5
9 8 6 6 87 24 87 24 8
Upvotes: 2
Reputation: 11981
you could use apply
like this:
df$first <- apply(df, 1, max)
df$second <- apply(df, 1, function(x) -sort(-x[1:5])[2])
df$third <- apply(df, 1, function(x) -sort(-x[1:5])[3])
v1 v2 v3 v4 v5 first second third
1 0 5 23 2 5 23 5 5
2 1 6 5 32 23 32 23 6
3 2 3 24 6 65 65 24 6
4 3 21 87 58 86 87 86 58
5 4 24 6 5 4 24 6 5
6 5 7 32 21 12 32 21 12
7 6 8 5 4 115 115 8 6
8 7 9 48 5 5 48 9 7
9 8 6 6 87 24 87 24 8
Upvotes: 0