跨列使用“rank”创建新变量

跨列使用“rank”创建新变量,r,R,我有一个我想不出来的问题,我几乎可以肯定这涉及到rank。假设我有一个广义形式的dfdf,有3个整数值的变量 id var1 var2 var3 1 23 8 30 2 1 2 3 3 4 5 1 4 100 80 60 我想创建三个新变量,将var1、var2和var3的值从大到小排列。比如说, id var1 var2 var3 var1_rank var2_rank v

我有一个我想不出来的问题,我几乎可以肯定这涉及到
rank
。假设我有一个广义形式的df
df
,有3个整数值的变量

id   var1   var2  var3
1    23     8     30
2    1      2     3
3    4      5     1
4    100    80    60
我想创建三个新变量,将
var1
var2
var3
的值从大到小排列。比如说,

id   var1   var2  var3   var1_rank   var2_rank   var3_rank
1    23     8     30      2          3            1
2    1      2     3       3          2            1 
3    4      5     1       2          1            3
4    100    80    60      1          2            3       
我该怎么做呢?谢谢

这里有一种方法:

data.frame(dat, 4 - t(apply(dat[, -1], 1, rank)))

## > data.frame(dat, 4 - t(apply(dat[, -1], 1, rank)))
##   id var1 var2 var3 var1.1 var2.1 var3.1
## 1  1   23    8   30      2      3      1
## 2  2    1    2    3      3      2      1
## 3  3    4    5    1      2      1      3
## 4  4  100   80   60      1      2      3
这里有一种方法:

data.frame(dat, 4 - t(apply(dat[, -1], 1, rank)))

## > data.frame(dat, 4 - t(apply(dat[, -1], 1, rank)))
##   id var1 var2 var3 var1.1 var2.1 var3.1
## 1  1   23    8   30      2      3      1
## 2  2    1    2    3      3      2      1
## 3  3    4    5    1      2      1      3
## 4  4  100   80   60      1      2      3
获取示例数据:

test <- read.table(text="id   var1   var2  var3
1    23     8     30
2    1      2     3
3    4      5     1
4    100    80    60",header=TRUE)
与旧数据帧连接

data.frame(test, ranks)
结果:

> data.frame(test,ranks)
  id var1 var2 var3 var1_rank var2_rank var3_rank
1  1   23    8   30         2         3         1
2  2    1    2    3         3         2         1
3  3    4    5    1         2         1         3
4  4  100   80   60         1         2         3
要使用base R获得@mnel的答案,还可以执行以下操作:

testres <- data.frame(test["id"],stack(test[2:4]))
testres$rank <- ave(testres$values,testres$id,FUN=function(x) rank(-x) )

> testres
   id values  ind rank
1   1     23 var1    2
2   2      1 var1    3
3   3      4 var1    2
4   4    100 var1    1
5   1      8 var2    3
6   2      2 var2    2
7   3      5 var2    1
8   4     80 var2    2
9   1     30 var3    1
10  2      3 var3    1
11  3      1 var3    3
12  4     60 var3    3
testres获取示例数据:

test <- read.table(text="id   var1   var2  var3
1    23     8     30
2    1      2     3
3    4      5     1
4    100    80    60",header=TRUE)
与旧数据帧连接

data.frame(test, ranks)
结果:

> data.frame(test,ranks)
  id var1 var2 var3 var1_rank var2_rank var3_rank
1  1   23    8   30         2         3         1
2  2    1    2    3         3         2         1
3  3    4    5    1         2         1         3
4  4  100   80   60         1         2         3
要使用base R获得@mnel的答案,还可以执行以下操作:

testres <- data.frame(test["id"],stack(test[2:4]))
testres$rank <- ave(testres$values,testres$id,FUN=function(x) rank(-x) )

> testres
   id values  ind rank
1   1     23 var1    2
2   2      1 var1    3
3   3      4 var1    2
4   4    100 var1    1
5   1      8 var2    3
6   2      2 var2    2
7   3      5 var2    1
8   4     80 var2    2
9   1     30 var3    1
10  2      3 var3    1
11  3      1 var3    3
12  4     60 var3    3

testres我认为在
long
格式下工作更容易(而且内存效率更高,因为
apply
将强制使用
矩阵
。下面是一种使用
重塑
数据的方法。table

library(data.table)
tlong <- reshape(data.table(test), direction ='long', varying = list(2:4), 
                 times = paste0('var',1:3), v.names = 'value')

# calculate the rank within each `id`

tlong[, rank := rank(-value), by = id]
tlong

##     id time value rank
##  1:  1 var1    23    2
##  2:  2 var1     1    3
##  3:  3 var1     4    2
##  4:  4 var1   100    1
##  5:  1 var2     8    3
##  6:  2 var2     2    2
##  7:  3 var2     5    1
##  8:  4 var2    80    2
##  9:  1 var3    30    1
## 10:  2 var3     3    1
## 11:  3 var3     1    3
## 12:  4 var3    60    3

# reshape to wide (if you want)

oldname <- paste0('var1',1:3)

twide <- reshape(tlong, direction = 'wide', timevar = 'time', idvar = 'id')
# reorder from value.var1, rank.var1,... to value.var1, value.var2,....rank.var1, rank.var2

setcolorder(twide, c('id', paste('value', oldname, sep ='.'), paste('rank', oldname, sep = '.'))
库(data.table)

t长我认为以
long
格式工作更容易(而且内存效率更高,因为
apply
将强制使用
矩阵
。下面是一种使用
重塑
数据的方法。table

library(data.table)
tlong <- reshape(data.table(test), direction ='long', varying = list(2:4), 
                 times = paste0('var',1:3), v.names = 'value')

# calculate the rank within each `id`

tlong[, rank := rank(-value), by = id]
tlong

##     id time value rank
##  1:  1 var1    23    2
##  2:  2 var1     1    3
##  3:  3 var1     4    2
##  4:  4 var1   100    1
##  5:  1 var2     8    3
##  6:  2 var2     2    2
##  7:  3 var2     5    1
##  8:  4 var2    80    2
##  9:  1 var3    30    1
## 10:  2 var3     3    1
## 11:  3 var3     1    3
## 12:  4 var3    60    3

# reshape to wide (if you want)

oldname <- paste0('var1',1:3)

twide <- reshape(tlong, direction = 'wide', timevar = 'time', idvar = 'id')
# reorder from value.var1, rank.var1,... to value.var1, value.var2,....rank.var1, rank.var2

setcolorder(twide, c('id', paste('value', oldname, sep ='.'), paste('rank', oldname, sep = '.'))
库(data.table)
特隆