regex - 提取左侧闭合间隔的断点

标签 regex r cut

我正在查看命令 cut() 的示例菜单(example(cut)),特别是这部分:

cut> aaa <- c(1,2,3,4,5,2,3,4,5,6,7)

cut> cut(aaa, 3)
[1] (0.994,3] (0.994,3] (3,5]     (3,5]     (3,5]     (0.994,3]
[7] (3,5]     (3,5]     (3,5]     (5,7.01]  (5,7.01] 
Levels: (0.994,3] (3,5] (5,7.01]

cut> cut(aaa, 3, dig.lab = 4, ordered = TRUE)
[1] (0.994,2.998] (0.994,2.998] (2.998,5.002] (2.998,5.002]
[5] (2.998,5.002] (0.994,2.998] (2.998,5.002] (2.998,5.002]
[9] (2.998,5.002] (5.002,7.006] (5.002,7.006]
Levels: (0.994,2.998] < (2.998,5.002] < (5.002,7.006]

cut> ## one way to extract the breakpoints
cut> labs <- levels(cut(aaa, 3))

cut> cbind(lower = as.numeric( sub("\\((.+),.*", "\\1", labs) ),
cut+       upper = as.numeric( sub("[^,]*,([^]]*)\\]", "\\1", labs) ))
     lower upper
[1,] 0.994  3.00
[2,] 3.000  5.00
[3,] 5.000  7.01

如果区间在右边闭合(如上所示),那么它向我展示了一种使用cbind() 提取数据断点的方法

现在,假设我的数据将被截断,但表明间隔在左侧闭合

cut(aaa, 3, dig.lab = 4, ordered = TRUE, right = FALSE)

现在如何使用相同的命令 cbind() 提取断点? (如果有更多的方法,不客气)

最佳答案

只需为您的模式使用类似于以下内容的内容,并改用 gsub:"\\[|\\]|\\(|\\)"

一个例子。

out <- levels(cut(aaa, 3, dig.lab = 4, ordered = TRUE, right = FALSE))
gsub("\\[|\\]|\\(|\\)", "", out)
# [1] "0.994,2.998" "2.998,5.002" "5.002,7.006"

而且,这里有一个快速读取数据的方法:

read.csv(text = gsub("\\[|\\]|\\(|\\)", "", out), header = FALSE)
#      V1    V2
# 1 0.994 2.998
# 2 2.998 5.002
# 3 5.002 7.006

仅供引用:无论间隔在左侧还是右侧闭合,相同的模式都适用。使用您的原始示例:

labs <- levels(cut(aaa, 3))
labs
# [1] "(0.994,3]" "(3,5]"     "(5,7.01]" 
read.csv(text = gsub("\\[|\\]|\\(|\\)", "", labs), header = FALSE)
#      V1   V2
# 1 0.994 3.00
# 2 3.000 5.00
# 3 5.000 7.01

至于替代方案,因为您只需要在使用 read.csv 之前删除第一个和最后一个字符,您也可以轻松使用 substr 而无需对正则表达式大惊小怪(如果那不是你的事):

substr(labs, 2, nchar(labs)-1)
# [1] "0.994,3" "3,5"     "5,7.01" 

更新:一个完全不同的选择

很明显,R 必须计算这些值并将它们存储为函数的一部分才能生成您看到的输出,因此操纵函数使其输出不同的东西并不难。

查看 cut.default 的代码,您会发现最后几行如下:

if (codes.only) 
    code
else factor(code, seq_along(labels), labels, ordered = ordered_result)

更改最后几行以输出一个 list 非常容易,其中包含 cut 的输出作为第一项,以及计算范围(来自 直接剪切函数,而不是从粘贴在一起的factor labels中提取。

例如,in the Gist I've posted at this link ,我已将这些行更改如下:

if (codes.only) 
  FIN <- code
else FIN <- factor(code, seq_along(labels), labels, ordered = ordered_result)
list(output = FIN, ranges = data.frame(lower = ch.br[-nb], upper = ch.br[-1L]))

现在,比较:

cut(aaa, 3)
#  [1] (0.994,3] (0.994,3] (3,5]     (3,5]     (3,5]     (0.994,3] (3,5]     (3,5]    
#  [9] (3,5]     (5,7.01]  (5,7.01] 
# Levels: (0.994,3] (3,5] (5,7.01]
CUT(aaa, 3)
# $output
# [1] (0.994,3] (0.994,3] (3,5]     (3,5]     (3,5]     (0.994,3] (3,5]     (3,5]    
# [9] (3,5]     (5,7.01]  (5,7.01] 
# Levels: (0.994,3] (3,5] (5,7.01]
# 
# $ranges
#   lower upper
# 1 0.994     3
# 2     3     5
# 3     5  7.01

并且,right = FALSE:

cut(aaa, 3, dig.lab = 4, ordered = TRUE, right = FALSE)
#  [1] [0.994,2.998) [0.994,2.998) [2.998,5.002) [2.998,5.002) [2.998,5.002)
#  [6] [0.994,2.998) [2.998,5.002) [2.998,5.002) [2.998,5.002) [5.002,7.006)
# [11] [5.002,7.006)
# Levels: [0.994,2.998) < [2.998,5.002) < [5.002,7.006)
CUT(aaa, 3, dig.lab = 4, ordered = TRUE, right = FALSE)
# $output
#  [1] [0.994,2.998) [0.994,2.998) [2.998,5.002) [2.998,5.002) [2.998,5.002)
#  [6] [0.994,2.998) [2.998,5.002) [2.998,5.002) [2.998,5.002) [5.002,7.006)
# [11] [5.002,7.006)
# Levels: [0.994,2.998) < [2.998,5.002) < [5.002,7.006)

# $ranges
#   lower upper
# 1 0.994 2.998
# 2 2.998 5.002
# 3 5.002 7.006

关于regex - 提取左侧闭合间隔的断点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19689397/

相关文章:

Python 正则表达式 : User Inputs Multiple Search Terms

java - Java 中的 replace() 和 replaceAll()

将 data.table 的值替换为另一个 data.table 的值

python - 使用 python ffmpeg 修剪音频文件

unix - 仅打印字符串中的第一个字段

linux - 空字符串作为 Cut 的输出字段分隔符

python - Pandas 正则表达式返回包含 U 或 UN 和数字的任何字符串

c# - 正则表达式删除某些字符周围不需要的空格

sql - 通过 RODBC : How do I deal with Hash Tables? 通过 RStudio 运行 SQL 查询

r - 将r中的列表写入excel文件