首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何对列表中的一些元素进行排序,同时保留其他元素的位置?

如何对列表中的一些元素进行排序,同时保留其他元素的位置?
EN

Stack Overflow用户
提问于 2021-12-30 19:04:40
回答 1查看 124关注 0票数 5

我有两种稍微不同的列表类型,我需要排序;但是,我只需要对列表中的部分进行排序,同时保持某些元素的位置(也就是说,它们的索引应该保持不变)。

首先,假设我有一个数字列表:

代码语言:javascript
运行
复制
x <- c(4, 8, 1, 7, 3, 0, 5, 2, 6, 9)

我知道,如果我只想对前5个元素进行排序,那么我可以这样做:

代码语言:javascript
运行
复制
x[1:5] <- sort(x[1:5])
x

# [1] 1 3 4 7 8 0 5 2 6 9

第二,如果我想对列表进行排序,但保留NAs,那么我可以这样做(虽然我确信有更好的方法来实现这一点):

代码语言:javascript
运行
复制
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))对列表进行排序,然后按组进行数字排序,但将NAs保留在它们原来的索引位置上?

代码语言:javascript
运行
复制
z <- c('B' , 'B1', 'B11', 'B2', 'A', 'C50', 'B21', NA, 'A5', 
       'B22', 'C', NA, 'C1', 'C11', NA, NA, 'C2', NA)

预期输出

代码语言:javascript
运行
复制
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   

我知道,如果我只想按字母顺序排序,那么我可以使用与上面相同的代码。然而,这些数字也不能正确排序。

代码语言:javascript
运行
复制
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),因为这些字母是字母数字的,并且是正确的数字排序。我知道我可以用ordermatch

代码语言:javascript
运行
复制
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),但我不确定如何实现它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-30 19:16:17

函数下面,为非NA元素('i1')创建一个索引,从向量的子集中提取字母,用自定义顺序指定的levels转换为一个levels,提取数字,将非NA元素提取回来并赋值,返回更新的向量。

代码语言:javascript
运行
复制
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
   
}

-testing

代码语言:javascript
运行
复制
f1(z)
[1] "C"   "C1"  "C2"  "C11" "C50" "A"   "A5"  NA    "B"   "B1"  "B2"  NA    "B11" "B21" NA    NA    "B22" NA   
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70535699

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档