r - 字符变量未排序
问题描述
tablecrt %>%
pivot_longer(Q1.Op:Q22.Buy, "q", "val") %>%
mutate(val = factor(val, levels = 9:1 )) %>%
tabyl(val, product.or.block, q, show_na = TRUE)
输出正在以这种格式打印
Q1.Op
Q10.JAR
Q12.Af
Q21.ex
Q3.Opi
Q4.JARaro
因为,您可以看到问题没有以正确的方式排序。我想把它作为
Q1.Op
Q3.Opi
Q4.JARaro
Q10.JAR
Q12.Af
提前致谢。
解决方案
它被正确排序:它是按字母顺序正确的。如果您想根据任意子字符串的整数转换进行排序,那么您需要这样做,语言不会为您猜测。
要将带有数字的任何内容作为数字进行排序,可能类似于:
numrank <- function(z, ...) rank(as.integer(sapply(regmatches(z, gregexpr("\\d+", z)), `[`, 1)), ...)
vec <- c("Q1.Op","Q10.JAR","Q12.Af","Q21.ex","Q3.Opi","Q4.JARaro","QZ")
tibble(v = vec) %>%
arrange(numrank(v, na.last=FALSE))
# # A tibble: 7 x 1
# v
# <chr>
# 1 QZ
# 2 Q1.Op
# 3 Q3.Opi
# 4 Q4.JARaro
# 5 Q10.JAR
# 6 Q12.Af
# 7 Q21.ex
还支持的是ties.method=...
,请参阅?rank
。
快速浏览“code-golfy”功能(正如@qdread 对其进行分类,我认为这是一个公平的标签)。如果我们debugonce(numrank)
运行一次,我们可以分解不同的部分。
首先,
gregexpr
旨在从字符串中识别和提取模式;它的返回仅仅是索引向量的列表(及其“长度”):z # [1] "Q1.Op" "Q10.JAR" "Q12.Af" "Q21.ex" "Q3.Opi" "Q4.JARaro" "QZ" str(gregexpr("\\d+", z)) # List of 7 # $ : int 2 # ..- attr(*, "match.length")= int 1 # ..- attr(*, "index.type")= chr "chars" # ..- attr(*, "useBytes")= logi TRUE # $ : int 2 # ..- attr(*, "match.length")= int 2 # ..- attr(*, "index.type")= chr "chars" # ..- attr(*, "useBytes")= logi TRUE # $ : int 2 # ..- attr(*, "match.length")= int 2 # ..- attr(*, "index.type")= chr "chars" # ..- attr(*, "useBytes")= logi TRUE # $ : int 2 # ..- attr(*, "match.length")= int 2 # ..- attr(*, "index.type")= chr "chars" # ..- attr(*, "useBytes")= logi TRUE # $ : int 2 # ..- attr(*, "match.length")= int 1 # ..- attr(*, "index.type")= chr "chars" # ..- attr(*, "useBytes")= logi TRUE # $ : int 2 # ..- attr(*, "match.length")= int 1 # ..- attr(*, "index.type")= chr "chars" # ..- attr(*, "useBytes")= logi TRUE # $ : int -1 # ..- attr(*, "match.length")= int -1 # ..- attr(*, "index.type")= chr "chars" # ..- attr(*, "useBytes")= logi TRUE
这很多,但请注意,第一个
int 2
表示匹配的子字符串从字符串位置 2 开始,这"match.length"= int 1
意味着第一个是一个字符长。向前跳到最后,看到int -1
,表示没有找到该模式。这是有道理的。regmatches(z, ...)
用于从gregexpr
.str(regmatches(z, gregexpr("\\d+", z))) # List of 7 # $ : chr "1" # $ : chr "10" # $ : chr "12" # $ : chr "21" # $ : chr "3" # $ : chr "4" # $ : chr(0)
请注意(再次)最后一个长度为 0,这是预期的。(如果正则表达式中有多个模式组,那么这些列表元素中的每一个都可能更长。)
sapply(..., `[`, 1)
是从列表的每个组件中提取第一个元素的技巧,一个不错的功能是,如果元素的内容长度为 0,则返回NA
,这实际上是我们在这里工作所需要的。最终,我们希望 this 的返回是一个character
向量(不是list
),只要输入。sapply(regmatches(z, gregexpr("\\d+", z)), `[`, 1) # [1] "1" "10" "12" "21" "3" "4" NA
as.integer
应该是不言自明的。(如果您有浮点数,则需要更新正则表达式,这将更改为as.numeric
。)输出需要能够指示元素的相对等级,因此我们只需将此向量传递给
rank
,以及用户可能想要的任何其他参数。例如,na.last=
将无编号元素推到行的前面(false)或末尾(true);并ties.method=
处理连续的相同数量的元素。
推荐阅读
- swift - 如何在 TableViewCell 中嵌入 AVPlayerViewController
- sql - 从同一个表中的两个单独的员工记录中获取新/旧值
- c# - 完成添加到集合时从 BlockingCollection.TakeFromAny 优雅退出
- visual-studio-code - 从 web 视图向扩展发送消息时如何传递回调函数
- php - 在没有类实例化的情况下调用方法
- azure - 用于警报的 Azure Application Insights Webhook 有效负载
- html - 如何使外部样式表中的类的 css 优先于元素的 css
- c# - 无法下载页面以单击使用 Puppeteer for C# 的按钮
- scheme - 如果原子不在列表中,将返回零的方案代码
- c++ - Windows 套接字编程:MFC CSocket 与 Win32 套接字