我有一个连续变量,我希望将其拆分为二进制数,返回一个数值向量(长度等于我的原始向量),其值与二进制值的值相关。每个bin应该具有大致相同数量的元素。
这个问题:splitting a continuous variable into equal sized groups描述了相关情况的一些技巧。例如,如果我从
开始x = c(1,5,3,12,5,6,7)
我可以使用cut()
来获取:
cut(x, 3, labels = FALSE)
[1] 1 2 1 3 2 2 2
这是不可取的,因为因子的值只是连续的整数,它们与我的向量中的基础原始值没有直接关系。
另一种可能性是cut2
:例如:
library(Hmisc)
cut2(x, g = 3, levels.mean = TRUE)
[1] 3.5 3.5 3.5 9.5 3.5 6.0 9.5
这更好,因为现在返回值与箱的值有关。从那以后它仍然不太理想:
我知道还有一些选项可以使用正则表达式从cut
或cut2
返回因子来获取区间的顶点或底点。这些看起来过于繁琐。
这只是一种需要一些不那么优雅的黑客攻击的情况吗?或者,是否有一些更容易实现的功能?
我目前的最佳努力如下:
MyDiscretize = function(x, N_Bins){
f = cut2(x, g = N_Bins, levels.mean = TRUE)
return(as.numeric(levels(f))[f])
}
我的目标是找到更快,更优雅,更容易适应使用任何一个端点的东西,而不仅仅是手段。
修改:
澄清一下:我想要的输出是:
(a)与我在cut2
示例中可以实现的内容相同,但不需要将因子转换为数字。
(b)如果可能,还可以轻松选择使用间隔的任何一个端点,而不是中点。
答案 0 :(得分:1)
也许不是很优雅,但应该是高效的。试试这个功能:
myCut<-function(x,breaks,retValues=c("means","highs","lows")) {
retValues<-match.arg(retValues)
if (length(breaks)!=1) stop("breaks must be a single number")
breaks<-as.integer(breaks)
if (is.na(breaks)||breaks<2) stop("breaks must greater than or equal to 2")
intervals<-seq(min(x),max(x),length.out=breaks+1)
bins<-findInterval(x,intervals,all.inside=TRUE)
if (retValues=="means") return(rowMeans(cbind(intervals[-(breaks+1)],intervals[-1]))[bins])
if (retValues=="highs") return(intervals[-1][bins])
intervals[-(breaks+1)][bins]
}
x = c(1,5,3,12,5,6,7)
myCut(x,3)
#[1] 2.833333 6.500000 2.833333 10.166667 6.500000 6.500000 6.500000
myCut(x,3,"highs")
#[1] 4.666667 8.333333 4.666667 12.000000 8.333333 8.333333 8.333333
myCut(x,3,"lows")
#[1] 1.000000 4.666667 1.000000 8.333333 4.666667 4.666667 4.666667
答案 1 :(得分:1)
像这样使用x = c(1,5,3,12,5,6,7)
:
假设:
ave(x,cut2(x,g = 3), FUN = mean)
[1] 3.5 3.5 3.5 9.5 3.5 6.0 9.5
平均:
ave(x,cut2(x,g = 3), FUN = min)
[1] 1 1 1 7 1 6 7
敏:
ave(x,cut2(x,g = 3), FUN = max)
[1] 5 5 5 12 5 6 12
最大:
ave(x,cut2(x,g = 3), FUN = sd)
[1] 1.914854 1.914854 1.914854 3.535534 1.914854 NA 3.535534
或标准差:
cut2
请注意区间内只有一个数据点的NA结果。
希望这就是你所需要的。
注意:
cut
中的参数g是分位数组的数量。组可能没有相同数量的数据点,并且间隔可能不具有相同的长度
另一方面,<option value="<?php echo $status['status'].' by '.$staff['name'].' '.$staff['surname']; ?>">Set to <?php echo ucwords($status['status']); ?> </option>
将间隔分成几个相等的长度。