按百分位数分割矢量

时间:2016-07-24 01:45:14

标签: r vector split

我需要将R中已排序的未知长度向量拆分为“前10%,...,最低10%” 所以,例如,如果我有vector <- order(c(1:98928)),我想将它分成10个不同的向量,每个向量代表总长度的大约10%。

我已尝试使用split <- split(vector, 1:10),但由于我不知道向量的长度,如果不是多个,我会收到此错误

  

数据长度不是拆分变量的倍数

即使它的多个和函数有效,split()也不会保持原始向量的顺序。这就是分裂给出的:

split(c(1:10) , 1:2)
$`1`
[1] 1 3 5 7 9

$`2`
[1]  2  4  6  8 10

这就是我想要的:

$`1`
[1] 1 2 3 4 5

$`2`
[1]  6  7  8  9 10

我是R的新手,我一直尝试很多事情但没有成功,有谁知道怎么做?

4 个答案:

答案 0 :(得分:6)

问题陈述

将每10%的排序向量x分成10个块。

请注意,有两种解释:

  1. 按矢量索引切割

    split(x, floor(10 * seq.int(0, length(x) - 1) / length(x)))
    
  2. 按矢量值(例如,分位数)切割

    split(x, cut(x, quantile(x, prob = 0:10 / 10, names = FALSE), include = TRUE))
    
  3. 在下文中,我将使用数据进行演示:

    set.seed(0); x <- sort(round(rnorm(23),1))
    

    特别是,我们的示例数据是正态分布而不是均匀分布,因此按索引切割和按值切割是非常不同的。

    结果

    按指数削减

    #$`0`
    #[1] -1.5 -1.2 -1.1
    #
    #$`1`
    #[1] -0.9 -0.9
    #
    #$`2`
    #[1] -0.8 -0.4
    #
    #$`3`
    #[1] -0.3 -0.3 -0.3
    #
    #$`4`
    #[1] -0.3 -0.2
    #
    #$`5`
    #[1] 0.0 0.1
    #
    #$`6`
    #[1] 0.3 0.4 0.4
    #
    #$`7`
    #[1] 0.4 0.8
    #
    #$`8`
    #[1] 1.3 1.3
    #
    #$`9`
    #[1] 1.3 2.4
    

    按分位数切割

    #$`[-1.5,-1.06]`
    #[1] -1.5 -1.2 -1.1
    #
    #$`(-1.06,-0.86]`
    #[1] -0.9 -0.9
    #
    #$`(-0.86,-0.34]`
    #[1] -0.8 -0.4
    #
    #$`(-0.34,-0.3]`
    #[1] -0.3 -0.3 -0.3 -0.3
    #
    #$`(-0.3,-0.2]`
    #[1] -0.2
    #
    #$`(-0.2,0.14]`
    #[1] 0.0 0.1
    #
    #$`(0.14,0.4]`
    #[1] 0.3 0.4 0.4 0.4
    #
    #$`(0.4,0.64]`
    #numeric(0)
    #
    #$`(0.64,1.3]`
    #[1] 0.8 1.3 1.3 1.3
    #
    #$`(1.3,2.4]`
    #[1] 2.4
    

答案 1 :(得分:3)

x <- 1:98
y <- split(x, ((seq(length(x))-1)*10)%/%length(x)+1)

说明:

seq(length(x)) = 1..98

seq(length(x))-1 = 0..97

(seq(length(x))-1)*10 = (0, 10, ..., 970)

# each number about 10% of values, totally 98
((seq(length(x))-1)*10)%/%length(x) = (0, ..., 0, 1, ..., 1, ..., 9, ..., 9) 

# each number about 10% of values, totally 98
seq(length(x))-1)*10)%/%length(x)+1 = (1, ..., 1, 2, ..., 2, ..., 10, ..., 10)  

# splits first ~10% of numbers to 1, next ~10% of numbers to 2 etc.
split(x, ((seq(length(x))-1)*10)%/%length(x)+1) 

答案 2 :(得分:3)

如果您在数据框中将矢量作为列(名为vec),则可以执行以下操作:

df$new_vec <- cut(df$vec , breaks = quantile(df$vec, c(0, .1,.., 1)), 
                labels=1:10, include.lowest=TRUE)

答案 3 :(得分:1)

如果对矢量进行了排序,那么您可以创建一个具有相同矢量长度的组变量并对其进行拆分。在实际情况下,它需要更多的努力,因为矢量的长度可能不是10的倍数,但对于您的玩具示例,您可以这样做:

n = 2
split(x, rep(1:n, each = length(x)/n))
# $`1`
# [1] 1 2 3 4 5

# $`2`
# [1]  6  7  8  9 10

一个真实案例,其中向量的长度不是组数的倍数:

vec = 1:13
n = 3
split(vec, sort(seq_along(vec)%%n))
# $`0`
# [1] 1 2 3 4

# $`1`
# [1] 5 6 7 8 9

# $`2`
# [1] 10 11 12 13