从因子变量的区间获取端点

时间:2016-11-17 21:20:51

标签: r intervals

设置 我从以下正常混合模型中对1,000,000个观测值进行抽样,并对观察结果进行分类,使得每个10,000 bin具有相同数量的观测值(即100)。这会为(a,b]形式的每个bin创建一个因子,其中ab是数字。

#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,但这似乎并未反映在上述输出中。

2 个答案:

答案 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
相关问题