通过排序分配值

时间:2016-04-19 10:21:58

标签: r dataframe

我的愚蠢问题如下: 拿df

df = data.frame(a= c(10,100,1,1000,1,1000), b = c(15,5,10,20,5,5))

         a  b
    1   10 15
    2  100  5
    3    1 10
    4 1000 20
    5    1  5
    6 1000  5

现在,我想使用以下基本原理分配a-column新值:

         a new_value
    1    1         1
    2    1         1
    3   10         2
    4  100         3
    5 1000         4
    6 1000         4

也就是说,按照他们的顺序重新编号,但是唯一的(我的意思是,我想要像

这样的东西
         a new_value
    1    1         1
    2    1         2
    3   10         3
    4  100         4
    5 1000         5
    6 1000         6

)。

问题是我无法做到,例如。

unique(df$a[order(df$a)]) = c(1:length(
    unique(df$a[order(df$a)]))

b柱同样的事情。 此外,由于我的实际数据帧非常大(约800 MB),我正在寻找最聪明(也是最快)的方法。 我在考虑类似于python字典,但我不确定它是否是正确的追求方式

我相信你们有正确的答案,它不应该那么复杂

为了清楚起见,最终的结果应该是

         a  b new.a new.b
    1   10 15     2     3
    2  100  5     3     1
    3    1 10     1     2
    4 1000 20     4     4
    5    1  5     1     1
    6 1000  5     4     1

1 个答案:

答案 0 :(得分:2)

我们可以使用data.table。将'data.frame'转换为'data.table'(setDT(df)),将order转换为'a',在按'a'分组后将'newvalue'创建为.GRP,然后将(b)分配(:=)为NULL。

library(data.table)
setDT(df)[order(a), newvalue := .GRP, by = a][order(a)][, b:= NULL][]

或者

setorder(setDT(df), a)[, newvalue :=.GRP ,a][, b:= NULL][]
#      a newvalue
#1:    1        1
#2:    1        1
#3:   10        2
#4:  100        3
#5: 1000        4
#6: 1000        4

更新

基于OP帖子中的更新

setDT(df)[order(a), new.a := .GRP , by = a][order(b), new.b := .GRP, b]
df
#      a  b new.a new.b
#1:   10 15     2     3
#2:  100  5     3     1
#3:    1 10     1     2
#4: 1000 20     4     4
#5:    1  5     1     1
#6: 1000  5     4     1

上述内容可以通过循环自动完成。

 setDT(df)
 nm1 <- names(df)
 for(j in seq_along(df)){
    df[order(eval(as.name(nm1[j]))), paste0("new.", names(df)[j]) := .GRP, by = c(nm1[j])][]
 }