R中单柱的复杂排序
我试图按一列中包含的代码对数据帧进行排序 这些代码背后的逻辑是: S/编号/编号/编号/数字(例如S120B)。数字并不总是3(例如S10K),字母也不总是存在(例如S2) 第一个代码是S1,该列表一直持续到S999,在那里变为S1A。然后转到S999A,然后转到S1B,依此类推 此外,泰尔内部也有完全不同的代码,如W23、E100等 我怎样才能根据这种病态的订购方案订购数据帧 MWE:R中单柱的复杂排序,r,R,我试图按一列中包含的代码对数据帧进行排序 这些代码背后的逻辑是: S/编号/编号/编号/数字(例如S120B)。数字并不总是3(例如S10K),字母也不总是存在(例如S2) 第一个代码是S1,该列表一直持续到S999,在那里变为S1A。然后转到S999A,然后转到S1B,依此类推 此外,泰尔内部也有完全不同的代码,如W23、E100等 我怎样才能根据这种病态的订购方案订购数据帧 MWE:code1.Create;) 或仅使用基本R: mre[order(mre$ID),] 按照您的指示,这是一
code1.Create;)
或仅使用基本R:
mre[order(mre$ID),]
按照您的指示,这是一个自定义功能:
codes <- c("S1", "S20D", "E44", "S550C", "S88A", "S420K", "W22")
complex_order <- function(codes) {
# Create empty order vector
final_order <- rep(NA,length(codes))
# First into account codes that do not match the S convention
not_in_convention <- !tolower(substr(codes,1,1)) == "s"
final_order[(length(codes)-sum(not_in_convention)+1):length(codes)] <- which(not_in_convention)
# Then check the ones that has a letter at the end
letter_at_end <- tolower(substr(codes,nchar(codes),nchar(codes))) %in% letters & !not_in_convention
for (idx in which(letter_at_end)) {
lettr <- tolower(substr(codes[idx],nchar(codes[idx]),nchar(codes[idx])))
lettr_value <- which(lettr == letters) * 1000 # Every letter means 1000 positions ahead
codes[idx] <- paste0("S",as.character(lettr_value))
}
# Now that we have all in the same code, order the values
values <- as.numeric(tolower(substr(codes[!not_in_convention],2,nchar(codes[!not_in_convention]))))
final_order[order(values)] <- which(!not_in_convention)
final_order
}
codes[complex_order(codes)]
[1] "S1" "S88A" "S550C" "S20D" "S420K" "E44" "W22"
代码
mre[order(mre$ID),]
codes <- c("S1", "S20D", "E44", "S550C", "S88A", "S420K", "W22")
complex_order <- function(codes) {
# Create empty order vector
final_order <- rep(NA,length(codes))
# First into account codes that do not match the S convention
not_in_convention <- !tolower(substr(codes,1,1)) == "s"
final_order[(length(codes)-sum(not_in_convention)+1):length(codes)] <- which(not_in_convention)
# Then check the ones that has a letter at the end
letter_at_end <- tolower(substr(codes,nchar(codes),nchar(codes))) %in% letters & !not_in_convention
for (idx in which(letter_at_end)) {
lettr <- tolower(substr(codes[idx],nchar(codes[idx]),nchar(codes[idx])))
lettr_value <- which(lettr == letters) * 1000 # Every letter means 1000 positions ahead
codes[idx] <- paste0("S",as.character(lettr_value))
}
# Now that we have all in the same code, order the values
values <- as.numeric(tolower(substr(codes[!not_in_convention],2,nchar(codes[!not_in_convention]))))
final_order[order(values)] <- which(!not_in_convention)
final_order
}
codes[complex_order(codes)]
[1] "S1" "S88A" "S550C" "S20D" "S420K" "E44" "W22"