R代码“整理”离散变量的值

时间:2014-09-20 04:38:09

标签: r

考虑这些数据:

set.seed(200914)
y <- round(runif(20, 5, 15))
y
table(y)

在实际应用中,y是一个分类变量,例如&#34;结果代码&#34;。我想重新编码R,使其值为1:n,同时保留顺序(有时变量可能是序数。)

答案是:

(ya <- y - min(y) + 1)
table(ya)

但是这个解决方案没有最小范围,这可能使后续代码效率低下。再试一次......

(suy <- sort(unique(y)))
(n <- length(suy))
yb <- y
for (i in 1:n) yb[which(y == suy[i])] <- i
table(yb)

yb正是我想要的,但我想知道我是否以最有效的方式计算它?

2 个答案:

答案 0 :(得分:3)

尝试

yc <- as.numeric(factor(y))

table(yc)
#yc
#1 2 3 4 5 6 7 8 
#1 4 1 1 6 3 3 1 

因为基本上你正在寻找的是因子代码(我认为)。

答案 1 :(得分:1)

尝试:

 yc <- match(y, sort(unique(y)))
 table(yc)

 #1 2 3 4 5 6 7 8 
 #1 4 1 1 6 3 3 1 

 all.equal(yb,yc)
 #[1] TRUE

另一个选项可能是findInterval

 table(findInterval(y, sort( unique(y))))
 #1 2 3 4 5 6 7 8 
 #1 4 1 1 6 3 3 1 

基准

set.seed(25)
y <- sample(1:20, 1e6,replace=TRUE)

f1 <- function() {suy <- sort(unique(y))
             n <- length(suy)
             yb <- y
             for (i in 1:n) yb[which(y == suy[i])] <- i
             table(yb)}

f2 <- function() {yc <- as.numeric(factor(y))
              table(yc)}


f3 <- function() {yd <- match(y, sort(unique(y)))
              table(yd)}

f4 <- function() {ye <- findInterval(y, sort(unique(y)))
              table(ye)}


library(microbenchmark)
microbenchmark(f1(), f2(), f3(), f4(), unit="relative", times=25L) 
#   Unit: relative
# expr      min       lq   median       uq      max neval
# f1() 1.198901 1.208551 1.235237 1.242697 1.600400    25
# f2() 3.745317 3.593736 3.593330 3.596990 3.488292    25
# f3() 1.000000 1.000000 1.000000 1.000000 1.000000    25
# f4() 1.017857 1.038056 1.047112 1.038731 1.014825    25