2016-04-13 87 views
6

我想离散化一个连续变量,将其切割成三个层次。我想为积极连续变量的日志(在这种情况下为收入)做同样的事情。离散化连续变量的日志

require(dplyr) 
set.seed(3) 
mydata = data.frame(realinc = rexp(10000)) 

summary(mydata) 

new = mydata %>% 
    select(realinc) %>% 
    mutate(logrealinc = log(realinc), 
     realincTercile = cut(realinc, 3), 
     logrealincTercile = cut(logrealinc, 3), 
     realincTercileNum = as.numeric(realincTercile), 
     logrealincTercileNum = as.numeric(logrealincTercile)) 

new[sample(1:nrow(new), 10),] 

我本来以为使用cut()会为每个这些变量的离散系数相同的水平(收入和日志收入),因为日志是一个单调函数。所以这里右边的两列应该是平等的,但这似乎不会发生。这是怎么回事?

> new[sample(1:nrow(new), 10),] 
     realinc logrealinc realincTercile logrealincTercile realincTercileNum logrealincTercileNum 
7931 0.2967813 -1.21475972 (-0.00805,2.83]  (-4.43,-1.15]     1     2 
9036 0.9511824 -0.05004944 (-0.00805,2.83]  (-1.15,2.15]     1     3 
8204 4.5365676 1.51217069  (2.83,5.66]  (-1.15,2.15]     2     3 
3136 2.0610693 0.72322490 (-0.00805,2.83]  (-1.15,2.15]     1     3 
9708 0.9655805 -0.03502581 (-0.00805,2.83]  (-1.15,2.15]     1     3 
5942 0.9149351 -0.08890215 (-0.00805,2.83]  (-1.15,2.15]     1     3 
4631 0.6987581 -0.35845064 (-0.00805,2.83]  (-1.15,2.15]     1     3 
7309 1.9532566 0.66949804 (-0.00805,2.83]  (-1.15,2.15]     1     3 
7708 0.4220254 -0.86268973 (-0.00805,2.83]  (-1.15,2.15]     1     3 
2965 1.3690976 0.31415186 (-0.00805,2.83]  (-1.15,2.15]     1     3 

编辑: @尼古拉的评论解释了问题的根源。似乎在cut的文档中,“等长间隔”是指连续参数空间中间隔的长度。我最初解释为“等长间隔”意味着分配给每个剪辑(在输出上)的元素数量是相等的(而不是输入)。

是否有一个函数可以完成我所描述的功能? - 每个输出级别的元素数量是否相等?等效地,newfunc(realinc)newfunc(logrealinc)的等级是相等的?

+3

'log'不是线性转换。假设'x'在1和5之间是均匀分布的。你是否期望'log(x)'在'log(1)'和'log(5)'之间均匀分布?在你的例子中,尝试'hist(new $ realinc)'和'hist(new $ logrealinc)'看看它们有什么不同。 'cut'只是以基本不变的间隔切割整个范围;一个元素可以很好地落入一个区间,并且它的日志可以进入另一个区域 – nicola

+0

@nicola谢谢,这是有帮助的。考虑到这一点,我已经更新了这个问题。 – Hatshepsut

+1

您可以搜索拆分向量等分块 – chinsoon12

回答

5

如果您希望您的关卡具有相同的居民身份,请查看quantile函数。试举例:

x<-cut(new$realinc,quantile(new$realinc,0:3/3)) 
y<-cut(new$logrealinc,quantile(new$logrealinc,0:3/3)) 
all(as.integer(x)==as.integer(y),na.rm=TRUE) 
#[1] TRUE 
table(x) 
#x 
#(0.000444,0.396]  (0.396,1.12]  (1.12,8.49] 
#   3333    3333    3333