2016-07-24 16 views
1

Ich muss einen sortierten unbekannten Längenvektor in R in "Top 10%, ..., unten 10%" teilen Also, zum Beispiel, wenn ich vector <- order(c(1:98928)) habe, möchte ich es in 10 teilen verschiedene Vektoren, von denen jeder etwa 10% der Gesamtlänge darstellt.einen Vektor nach Perzentil teilen

Ive versuchte split <- split(vector, 1:10) verwenden, aber als ich die Länge des Vektors weiß nicht, bekomme ich diesen Fehler, wenn sie nicht mehr

Datenlänge keine

mehr geteilte Variable

Und selbst Wenn sein Vielfaches und die Funktion funktioniert, behält split() nicht die Reihenfolge meines ursprünglichen Vektors bei. Dies ist, was Split gibt:

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

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

Und das ist, was ich will:

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

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

Im Neuling in R und Ive versucht, viele Dinge ohne Erfolg, hat jemand weiß, wie dies zu tun?

Antwort

3

Problemstellung

Pause eine sortierte Vektor x alle 10% in 10 Stücke schneiden.

Hinweis gibt es zwei Interpretation dafür:

  1. Schneiden von Vektorindex:

    split(x, floor(10 * seq.int(0, length(x) - 1)/length(x))) 
    
  2. Schneiden von Vektorwerte (etwa Quantile):

    split(x, cut(x, quantile(x, prob = 0:10/10, names = FALSE), include = TRUE)) 
    

Im Folgenden werde ich Demonstration unter Verwendung von Daten machen:

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

Besonders Normalerweise eher verteilt, unsere Beispieldaten als gleichmäßig verteilt, so durch den Index und das Schneiden von Wert Schneiden sind wesentlich verschieden.

Ergebnis

Schneiden von Index

#$`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 

Schneiden von Quantil

#$`[-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

Wenn der Vektor sortiert ist, können Sie einfach eine Gruppenvariable mit der gleichen Länge des Vektors erstellen und darauf aufteilen. Im realen Fall wird es ein wenig mehr Aufwand, da die Länge des Vektors erfordert ein Vielfach von 10, sondern für Ihr Spielzeug Beispiel kann nicht sein, können Sie tun:

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 

Ein echtes Fallbeispiel, wo die Länge des Vektors nicht ein Vielfaches der Anzahl der Gruppen:

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 
3
x <- 1:98 
y <- split(x, ((seq(length(x))-1)*10)%/%length(x)+1) 

Erläuterung:

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) 
1

Wenn Sie Ihren Vektor als eine Spalte (genannt vec) in einem Datenrahmen haben, können Sie einfach so etwas tun:

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