giá trị phổ biến nhất được chuyển thành 1, giá trị phổ biến thứ hai thành 2, v.v.
Bạn có thể sử dụng table
, sort
, factor
:
convert <- function(x) as.integer(factor(x, levels = names(sort(-table(x)))))
num1 <- convert(df1$snp1)
num2 <- convert(df$2snp2)
áp dụng điều này cho tất cả các cột trong một cách tiện dụng?
Sử dụng lapply
:
df2 <- as.data.frame(lapply(df1, FUN = convert))
Thảo luận:
@thelatemail đề cập đến khả năng sử dụng match()
. Việc sử dụng levels()
giả định rằng tất cả các cột của df1
là các yếu tố dễ dàng. Thường thì điều này là đúng, trừ khi một số người, như tôi, đã đặt options(stringsAsFactors = FALSE)
trong tệp khởi động R. Tôi sẽ thay thế levels()
bằng names()
, vì vậy ý tưởng của anh ấy sẽ hoạt động đối với cả đầu vào chuỗi và yếu tố đầu vào.
convert2 <- function(x) {
tab <- table(x)
match(x, names(tab)[order(-tab)])
}
câu hỏi đầu tiên của chúng tôi là, là convert2()
nhanh hơn đáng kể so với convert()
?
Chúng ta định nghĩa một hàm đồ chơi để đo lường hiệu suất giữa hai chức năng:
timing <- function(n, rep, FACTOR = FALSE, FUN1, FUN2) {
## sample data
x <- c("AA", "AT", "TT")[sample(1:3, n, replace = TRUE)]
if (FACTOR) x <- factor(x)
## method 1: as.integer(factor())
t1 <- system.time(for (k in 1:rep) {tmp <- FUN1(x); tmp <- FUN1(x); tmp <- FUN1(x); tmp <- FUN1(x)})
## method 2: match()
t2 <- system.time(for (k in 1:rep) {tmp <- FUN2(x); tmp <- FUN2(x); tmp <- FUN2(x); tmp <- FUN2(x)})
## timing summary
cat("FUN1\n"); print(t1)
cat("FUN2\n"); print(t2)
}
Đối với chuỗi đầu vào nhân vật ta có:
> timing(n = 20000, rep = 1000, FACTOR = FALSE, FUN1 = convert, FUN2 = convert2)
FUN1 ## convert(), using as.integer(factor())
user system elapsed
18.772 0.212 19.052
FUN2 ## convert2(), using match()
user system elapsed
17.792 0.100 17.920
Đối với đầu vào yếu tố, ta có:
> timing(n = 20000, rep = 1000, FACTOR = TRUE, FUN1 = convert, FUN2 = convert2)
FUN1 ## convert(), using as.integer(factor())
user system elapsed
17.180 0.144 17.384
FUN2 ## convert2(), using match()
user system elapsed
15.500 0.168 15.693
Vì vậy:
- khi đầu vào là các yếu tố, cả hai phương pháp đều nhanh hơn;
convert2()
nhanh hơn khoảng 5% - 10% so với convert1()
.
Bây giờ hãy hạn chế rằng chúng tôi có yếu tố đầu vào, chúng tôi thực sự có thể thực hiện nhanh hơn convert2()
. Hãy xem xét:
## only works for factor input!!
convert3 <- function(x) {
tab <- table(x)
match(as.integer(x), (seq_along(tab))[order(-tab)])
}
Ở đây, chúng tôi đã sử dụng đối sánh số nguyên.Hãy so sánh convert2()
và convert3()
:
> timing(n = 20000, rep = 1000, FACTOR = TRUE, FUN1 = convert2, FUN2 = convert3)
FUN1 ## convert2(), using string match
user system elapsed
15.168 0.156 15.351
FUN2 ## convert3(), using integer match
user system elapsed
14.032 0.116 14.174
'data.frame (lapply (df1, function (x) {as.numeric (yếu tố (x, mức = tên (loại (-table (x)))))))) ' – alistaire