我正在查看命令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()
提取我的断点?(如果有更多的方法,欢迎使用)
2条答案
按热度按时间3yhwsihp1#
只需为您的模式使用以下内容,并使用
gsub
:"\\[|\\]|\\(|\\)"
。举个例子
这里有一个快速读取数据的方法:
仅供参考:无论间隔是在左侧闭合还是在右侧闭合,都可以使用相同的模式。使用原始示例:
至于替代方案,因为你只需要在使用
read.csv
之前去掉第一个和最后一个字符,所以你也可以轻松地使用substr
,而不必对正则表达式大惊小怪(如果这不是你的事情):更新:一个完全不同的选择
由于很明显R必须计算这些值并将其存储为函数的一部分,以便生成您看到的输出,因此操纵函数以使其输出不同的东西并不太困难。
查看
cut.default
的代码,您会发现最后几行代码如下:很容易将最后几行改为输出
list
,其中包含cut
的输出作为第一项,以及计算的范围(直接从cut
函数中,而不是从粘贴在一起的factor
labels
中提取)。例如,in the Gist I've posted at this link,我对这些行做了如下修改:
现在,比较:
right = FALSE
:uxhixvfz2#
我发现这个问题的大多数答案都是关于反转构造的字符串或编写自己的cut替代版本。
然而,R有一个函数
trace()
,它给了你一个开箱即用的机会来注入代码到一个函数中。你可以用它来“破解”一个函数的副作用,比如提取一个不返回的内部对象。我使用
at=7
是因为我事先检查了函数体中的breaks变量已经计算好并且不再更改的位置。你可以通过as.list(body(cut.default))
找到这一点。7
可能需要在未来的R版本中进行更改。我使用带引号的表达式
these_breaks<<-breaks
将内部breaks
复制到全局env中的一个对象。在包代码中,可以使用预定义的env更优雅地完成此操作。