按行模式排序行

3

我希望重新排列一个类似这样的数据框的行:

qs=c("q11", "q22", "q2", "q6", "q10")
ans=rep(1,times=length(qs))
df=data.frame(qs,ans)
arrange(df,qs)

 qs ans
1 q10   1
2 q11   1
3  q2   1
4 q22   1
5  q6   1

然而,我希望行的排序按照更加合理的顺序进行,例如:

 qs ans
1  q2   1
2  q6   1
3 q10   1
4 q11   1
5 q22   1

有人能帮我解决这个问题吗?

2个回答

4

使用 R 基础语言:

df <- df[order(as.integer(gsub("q", "", as.character(df$qs)))), ]

例如,对于您提供的df,其结果如下:

   qs ans
3  q2   1
4  q6   1
5 q10   1
1 q11   1
2 q22   1

您可能会注意到重新排序后的行名称不是1、2、3、4、5;您可以执行以下操作:
rownames(df) <- 1:nrow(df)

为了让它看起来更好:
   qs ans
1  q2   1
2  q6   1
3 q10   1
4 q11   1
5 q22   1

你的回答很有帮助,谢谢。正如已经评论给akun的那样,与此相关的问题是,如果行的形式为“qs=c(“Q.1a”,“Q.1b”,“Q.10a”,“Q.10b”,“Q.10c”,“Q.6a”,“Q.6b”)”,在这种情况下,两个答案都不起作用。 - msh855

2

在将“qs”转换为 character 类之后,我们使用 gtools 中的 mixedorder

library(gtools)
df1 <- `row.names<-`(df[mixedorder(as.character(df$qs)),], NULL)
df1
#   qs ans
#1  q2   1
#2  q6   1
#3 q10   1
#4 q11   1
#5 q22   1

或者我们也可以使用base R,通过gsub除去非数字字符,将其转换为numeric类型,并对行进行order排序。

df[order(as.numeric(gsub("\\D+", "", df$qs))),]

没有冒犯akrun的意思,但是为什么你要使用\row.names<-``这种方式来让代码变得更难读和维护(特别是对于新手),而不是使用第二行呢? - talat
因为我注意到另一个帖子已经发布了 rownames(df) <- ..,如果我使用它就会变得冗余。此外,有可能让提问者认为我的答案不完整,所以我冒险这样做,避免可能的抄袭。 - akrun
@akrun,你的回答很有帮助,谢谢。与此相关的一个问题是,如果行的形式是'qs=c("Q.1a", "Q.1b", "Q.10a", "Q.10b", "Q.10c", "Q.6a", "Q.6b")',在这种情况下,两个答案都不起作用。 - msh855
@msh855 或许是 qs[mixedorder(sub(".*\\.", "", qs))] #[1] "Q.1a" "Q.1b" "Q.6a" "Q.6b" "Q.10a" "Q.10b" "Q.10c"` - akrun
1
@akrun,不要介意,这只是一个错误 :)。 - msh855

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接