设置
我从以下正常混合模型中对1,000,000
个观测值进行抽样,并对观察结果进行分类,使得每个10,000
bin具有相同数量的观测值(即100
)。这会为(a,b]
形式的每个bin创建一个因子,其中a
和b
是数字。
#Random sample
set.seed(1234)
X = ks::rnorm.mixt(n=1000000,mus=c(0.2,0.8),sigmas=c(0.04,0.01),props=c(0.95,0.05))
#Bins based on random sample with ~100 observations in each bins
bins = ggplot2::cut_number(X,10000)
dat = data.frame(X,bins)
问题
我想从因子a
中提取数字b
和(a,b]
。这是垃圾箱的样子:
> head(table(bins))
bins
[0.00501617,0.0518875] (0.0518875,0.0594831] (0.0594831,0.0640679]
100 100 100
(0.0640679,0.0670062] (0.0670062,0.0694194] (0.0694194,0.0717924]
100 100 100
> tail(table(bins),20)
bins
(0.817766,0.818032] (0.818032,0.8183] (0.8183,0.818544] (0.818544,0.818879]
100 100 100 100
(0.818879,0.819112] (0.819112,0.819394] (0.819394,0.819664] (0.819664,0.819979]
100 100 100 100
(0.819979,0.820328] (0.820328,0.820727] (0.820727,0.821118] (0.821118,0.82158]
100 100 100 100
(0.82158,0.822109] (0.822109,0.822646] (0.822646,0.823253] (0.823253,0.82408]
100 100 100 100
(0.82408,0.825026] (0.825026,0.826417] (0.826417,0.828651] (0.828651,0.84424]
100 100 100 100
正如您所看到的,因素中的数字不一定具有相同的位数,并且可以在0之前(例如(0.0518875,0.0594831]
)。
我最初尝试使用
提取数字部分endpts=na.omit(as.numeric(unlist(strsplit(as.character(unlist(bins)),"[^0-9]+"))))
对于上面的bin((0.0518875,0.0594831]
),将输出此过程
518875 594831
,但由于尾随零消失,因此可以将其映射到多个值(例如0.518875 0.594831
)。此外,存在其中一个或两个数字具有不同数字位数(例如(0.818032,0.8183]
)的区间。输出中缺乏统一性在尝试获取端点时给我带来了问题。最终,我想获得左右端点。有什么建议吗?
编辑我还查看了使用ggplot2::cut_number
函数的cut
代码。 cut
中数字位数的默认输入为dig.lab=3
,但这似乎并未反映在上述输出中。
答案 0 :(得分:2)
我认为你可以利用结构(a, b]
。我没有尝试过真实的数据,但这是我的尝试:
s <- c("(0.0518875,0.0594831]", "0.818032,0.8183]")
lapply(strsplit(s, ","), function(x) gsub("\\(|]", "", x))
[[1]]
[1] "0.0518875" "0.0594831"
[[2]]
[1] "0.818032" "0.8183"
如果您想要号码,可以将其更改为as.numeric
。
答案 1 :(得分:2)
这种经过轻微测试的方法:
unique( as.numeric( unlist(
strsplit( gsub( "[][(]" , "", levels(bins)[1:5] ) , ","))))
我已经学会了从内到外&#34;中读取嵌套的R代码。第一个(1)使用字符类模式删除侧翼&#34;(&#34;,&#34; [&#34;和&#34;]&#34;然后(2)在逗号上拆分,(3)&#34;矢量化&#34;列表结构unlist
,(4)然后转换为数字,最后(5)删除重复。这显示它使用换行符进行格式化:
unique( # (5)
as.numeric( # (4)
unlist( # (3)
strsplit( # (2)
gsub( "[][(]" , "", levels(bins)[1:5] ) , ",") # (1)
)))
这是在您的示例中进行了测试,并使用前5个级别生成了一个较小的示例:
unique( as.numeric( unlist( strsplit( gsub( "[][(]" , "", levels(bins)[1:5] ) , ","))))
[1] 0.00501617 0.05188750 0.05948310 0.06406790 0.06700620 0.06941940
我把单词&#34; vectorizes&#34;在引号中,因为它并不是R术语中该词的含义,它指的是返回与其输入相等长度的向量的操作。
我的建议的结果是将不中的小数点(句点)用作分割标准,并与我的代码提供的内容保持联系。您不清楚是否只需要每个项目的唯一值或值:
endpts= na.omit( as.numeric( unlist( strsplit( as.character( unlist(bins)),"[^0-9.]+"))))
head(endpts)
#[1] 0.216698 0.216709 0.243665 0.243682 0.201100 0.201114
end2 <- unique( as.numeric( unlist( strsplit( gsub( "[][(]" , "", levels(bins) ) , ","))))
head(end2)
#[1] 0.00501617 0.05188750 0.05948310 0.06406790 0.06700620 0.06941940
length(endpts)
#[1] 2000000
length(end2)
#[1] 10001