我有兩種稍微不同型別的串列需要排序;然而,我只需要對串列的部分進行排序,同時保留一些元素(即它們的索引應該保持不變)。
首先,假設我有一個數字串列:
x <- c(4, 8, 1, 7, 3, 0, 5, 2, 6, 9)
我知道如果我只想對前 5 個元素進行排序,那么我可以這樣做:
x[1:5] <- sort(x[1:5])
x
# [1] 1 3 4 7 8 0 5 2 6 9
其次,如果我想對串列進行排序,但保留 NA,那么我可以做這樣的事情(盡管我確信有更好的方法來做到這一點):
y <- c(4, 8, 1, NA, NA, 7, 3, 0, 5, 2, NA, 6, NA, 9)
y[which(is.na(y)==FALSE)] <- sort(y[which(is.na(y)==FALSE)])
y
# [1] 0 1 2 NA NA 3 4 5 6 7 NA 8 NA 9
問題:如何按組對包含字母數字字符的串列進行排序?所以,我想首先按預定義的字母順序(即c(C, A, B))對串列進行排序,然后按組按數字排序,但將 NA 保留在其原始索引位置?
z <- c('B' , 'B1', 'B11', 'B2', 'A', 'C50', 'B21', NA, 'A5',
'B22', 'C', NA, 'C1', 'C11', NA, NA, 'C2', NA)
預期產出
c('C', 'C1', 'C2', 'C11', 'C50', 'A', 'A5', NA, 'B', 'B1', 'B2', NA, 'B11', 'B21', NA, NA, 'B22', NA)
# [1] "C" "C1" "C2" "C11" "C50" "A" "A5" NA "B" "B1" "B2" NA "B11" "B21" NA NA "B22" NA
我知道如果我只想按字母順序排序,那么我可以使用與上面相同的代碼。但是,這些也沒有按數字正確排序。
z[which(is.na(z)==FALSE)] <- sort(z[which(is.na(z)==FALSE)])
z
# [1] "A" "A5" "B" "B1" "B11" "B2" "B21" NA "B22" "C" "C1" NA "C11" "C2" NA NA "C50" NA
但是,我不確定如何將字母的順序更改為 ,c(C, A, B)因為這些是字母數字并按數字正確排序。我知道我可以使用order和match:
f <- sort(z[which(is.na(z)==FALSE)])
z[which(is.na(z)==FALSE)] <- f[order(match(f, c("C","A","B")))]
# [1] "C" "A" "B" "A5" "B1" "B11" "B2" NA "B21" "B22" "C1" NA "C11" "C2" NA NA "C50" NA
但只有在存在完美匹配時才會改變(因此只有 C、A 和 B 移動到串列的開頭,然后組丟失),并且必須將完整的字母數字串列提供給match. 我確信有一種簡單的方法可以做到這一點(例如,grepl),但我不確定如何實作它。
uj5u.com熱心網友回復:
下面的功能,創建用于非NA元素的索引(“I1”),提取從矢量的所述子集的字母,轉換為factor與levels在自定義順序指定,提取數字, order所述非NA元素提取的矢量和分配回來,回傳更新后的向量
f1 <- function(vec) {
i1 <- !is.na(vec)
v1 <- factor(sub("\\d ", "", vec[i1]), levels = c("C", "A", "B"))
v2 <- sub("\\D ", "", vec[i1])
v2[!nzchar(v2)] <- 0
v2 <- as.numeric(v2)
vec[i1] <- vec[i1][order(v1, v2)]
vec
}
-測驗
f1(z)
[1] "C" "C1" "C2" "C11" "C50" "A" "A5" NA "B" "B1" "B2" NA "B11" "B21" NA NA "B22" NA
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/399276.html
上一篇:用零“填充”串列中缺失的位置
