[r] R에서 벡터를 청크로 나눕니다.

R에서 벡터를 동일한 크기의 n 개의 덩어리로 나눠야합니다.이를 수행 할 기본 함수를 찾을 수 없습니다. 또한 구글은 나를 어디에도 데려다주지 않았다. 그래서 여기에 내가 생각 해낸 것이 누군가에게 도움이되기를 바랍니다.

x <- 1:10
n <- 3
chunk <- function(x,n) split(x, factor(sort(rank(x)%%n)))
chunk(x,n)
$`0`
[1] 1 2 3

$`1`
[1] 4 5 6 7

$`2`
[1]  8  9 10

모든 의견, 제안 또는 개선은 정말 환영하고 감사합니다.

건배, 세바스찬



답변

d를 20 크기의 덩어리로 분할 한 라이너.

split(d, ceiling(seq_along(d)/20))

자세한 내용 : 나는 당신이 필요로하는 모든 생각 seq_along(), split()그리고 ceiling():

> d <- rpois(73,5)
> d
 [1]  3  1 11  4  1  2  3  2  4 10 10  2  7  4  6  6  2  1  1  2  3  8  3 10  7  4
[27]  3  4  4  1  1  7  2  4  6  0  5  7  4  6  8  4  7 12  4  6  8  4  2  7  6  5
[53]  4  5  4  5  5  8  7  7  7  6  2  4  3  3  8 11  6  6  1  8  4
> max <- 20
> x <- seq_along(d)
> d1 <- split(d, ceiling(x/max))
> d1
$`1`
 [1]  3  1 11  4  1  2  3  2  4 10 10  2  7  4  6  6  2  1  1  2

$`2`
 [1]  3  8  3 10  7  4  3  4  4  1  1  7  2  4  6  0  5  7  4  6

$`3`
 [1]  8  4  7 12  4  6  8  4  2  7  6  5  4  5  4  5  5  8  7  7

$`4`
 [1]  7  6  2  4  3  3  8 11  6  6  1  8  4


답변

chunk2 <- function(x,n) split(x, cut(seq_along(x), n, labels = FALSE)) 


답변

simplified version...
n = 3
split(x, sort(x%%n))


답변

ggplot2 함수를 사용해보십시오 cut_number:

library(ggplot2)
x <- 1:10
n <- 3
cut_number(x, n) # labels = FALSE if you just want an integer result
#>  [1] [1,4]  [1,4]  [1,4]  [1,4]  (4,7]  (4,7]  (4,7]  (7,10] (7,10] (7,10]
#> Levels: [1,4] (4,7] (7,10]

# if you want it split into a list:
split(x, cut_number(x, n))
#> $`[1,4]`
#> [1] 1 2 3 4
#> 
#> $`(4,7]`
#> [1] 5 6 7
#> 
#> $`(7,10]`
#> [1]  8  9 10


답변

이것은 당신이 가진 것과 다르게 나눌 것이지만, 여전히 좋은 목록 구조입니다.

chunk.2 <- function(x, n, force.number.of.groups = TRUE, len = length(x), groups = trunc(len/n), overflow = len%%n) {
  if(force.number.of.groups) {
    f1 <- as.character(sort(rep(1:n, groups)))
    f <- as.character(c(f1, rep(n, overflow)))
  } else {
    f1 <- as.character(sort(rep(1:groups, n)))
    f <- as.character(c(f1, rep("overflow", overflow)))
  }

  g <- split(x, f)

  if(force.number.of.groups) {
    g.names <- names(g)
    g.names.ordered <- as.character(sort(as.numeric(g.names)))
  } else {
    g.names <- names(g[-length(g)])
    g.names.ordered <- as.character(sort(as.numeric(g.names)))
    g.names.ordered <- c(g.names.ordered, "overflow")
  }

  return(g[g.names.ordered])
}

형식화 방법에 따라 다음을 제공합니다.

> x <- 1:10; n <- 3
> chunk.2(x, n, force.number.of.groups = FALSE)
$`1`
[1] 1 2 3

$`2`
[1] 4 5 6

$`3`
[1] 7 8 9

$overflow
[1] 10

> chunk.2(x, n, force.number.of.groups = TRUE)
$`1`
[1] 1 2 3

$`2`
[1] 4 5 6

$`3`
[1]  7  8  9 10

이 설정을 사용하여 몇 가지 타이밍 실행 :

set.seed(42)
x <- rnorm(1:1e7)
n <- 3

그러면 다음과 같은 결과가 나타납니다.

> system.time(chunk(x, n)) # your function 
   user  system elapsed
 29.500   0.620  30.125

> system.time(chunk.2(x, n, force.number.of.groups = TRUE))
   user  system elapsed
  5.360   0.300   5.663 

편집 : 내 함수에서 as.factor ()에서 as.character ()로 변경하면 두 배 빨라졌습니다.


답변

더미에 대한 몇 가지 변형 …

> x <- 1:10
> n <- 3

factor여기서 함수 를 사용할 필요는 없지만 여전히 sort첫 번째 벡터는 다음과 1 2 3 10같습니다.

> chunk <- function(x, n) split(x, sort(rank(x) %% n))
> chunk(x,n)
$`0`
[1] 1 2 3
$`1`
[1] 4 5 6 7
$`2`
[1]  8  9 10

또는 문자 색인을 할당 할 수 있으며 위의 왼쪽 진드기의 숫자는 다음과 같습니다.

> my.chunk <- function(x, n) split(x, sort(rep(letters[1:n], each=n, len=length(x))))
> my.chunk(x, n)
$a
[1] 1 2 3 4
$b
[1] 5 6 7
$c
[1]  8  9 10

또는 벡터에 저장된 평문 이름을 사용할 수 있습니다. sort연속 값을 얻기 위해을 사용 x하면 레이블이 알파벳순으로 표시됩니다.

> my.other.chunk <- function(x, n) split(x, sort(rep(c("tom", "dick", "harry"), each=n, len=length(x))))
> my.other.chunk(x, n)
$dick
[1] 1 2 3
$harry
[1] 4 5 6
$tom
[1]  7  8  9 10


답변

기본 R 사용 rep_len:

x <- 1:10
n <- 3

split(x, rep_len(1:n, length(x)))
# $`1`
# [1]  1  4  7 10
# 
# $`2`
# [1] 2 5 8
# 
# $`3`
# [1] 3 6 9

정렬 된 인덱스를 원한다면 이미 언급했듯이 간단히 :

split(x, sort(rep_len(1:n, length(x))))
# $`1`
# [1] 1 2 3 4
# 
# $`2`
# [1] 5 6 7
# 
# $`3`
# [1]  8  9 10