R中单柱的复杂排序

R中单柱的复杂排序,r,R,我试图按一列中包含的代码对数据帧进行排序 这些代码背后的逻辑是: S/编号/编号/编号/数字(例如S120B)。数字并不总是3(例如S10K),字母也不总是存在(例如S2) 第一个代码是S1,该列表一直持续到S999,在那里变为S1A。然后转到S999A,然后转到S1B,依此类推 此外,泰尔内部也有完全不同的代码,如W23、E100等 我怎样才能根据这种病态的订购方案订购数据帧 MWE:code1.Create;) 或仅使用基本R: mre[order(mre$ID),] 按照您的指示,这是一

我试图按一列中包含的代码对数据帧进行排序

这些代码背后的逻辑是:

S/编号/编号/编号/数字(例如S120B)。数字并不总是3(例如S10K),字母也不总是存在(例如S2)

第一个代码是S1,该列表一直持续到S999,在那里变为S1A。然后转到S999A,然后转到S1B,依此类推

此外,泰尔内部也有完全不同的代码,如W23、E100等

我怎样才能根据这种病态的订购方案订购数据帧

MWE:
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"