sourcecode

두 개 이상의 벡터에서 모든 요소의 고유한 조합

copyscript 2023. 6. 8. 22:27
반응형

두 개 이상의 벡터에서 모든 요소의 고유한 조합

저는 R에서 크기가 다른 두 벡터에서 모든 요소의 고유한 조합을 만들려고 합니다.

예를 들어, 첫 번째 벡터는 다음과 같습니다.

a <- c("ABC", "DEF", "GHI")

그리고 두 번째는 현재 문자열로 저장된 날짜입니다.

b <- c("2012-05-01", "2012-05-02", "2012-05-03", "2012-05-04", "2012-05-05")

이와 같은 두 개의 열로 데이터 프레임을 만들어야 합니다.

> data
    a          b
1  ABC 2012-05-01
2  ABC 2012-05-02
3  ABC 2012-05-03
4  ABC 2012-05-04
5  ABC 2012-05-05
6  DEF 2012-05-01
7  DEF 2012-05-02
8  DEF 2012-05-03
9  DEF 2012-05-04
10 DEF 2012-05-05
11 GHI 2012-05-01
12 GHI 2012-05-02
13 GHI 2012-05-03
14 GHI 2012-05-04
15 GHI 2012-05-05

그래서 기본적으로, 저는 하나의 벡터(a)의 모든 요소를 두 번째 벡터(b)의 모든 요소와 나란히 고려하여 고유한 조합을 찾고 있습니다.

이상적인 솔루션은 더 많은 입력 벡터로 일반화됩니다.


참고 항목:
조합 행렬을 생성하는 방법

이것은 아마도 당신이 추구하는 것일 것입니다.

> expand.grid(a,b)
   Var1       Var2
1   ABC 2012-05-01
2   DEF 2012-05-01
3   GHI 2012-05-01
4   ABC 2012-05-02
5   DEF 2012-05-02
6   GHI 2012-05-02
7   ABC 2012-05-03
8   DEF 2012-05-03
9   GHI 2012-05-03
10  ABC 2012-05-04
11  DEF 2012-05-04
12  GHI 2012-05-04
13  ABC 2012-05-05
14  DEF 2012-05-05
15  GHI 2012-05-05

결과 순서가 원하는 순서가 아닌 경우 나중에 정렬할 수 있습니다.인수 이름을 다음으로 지정하는 경우expand.grid열 이름이 됩니다.

df = expand.grid(a = a, b = b)
df[order(df$a), ]

그리고.expand.grid임의의 수의 입력 열로 일반화합니다.

tidyr패키지는 좋은 대안을 제공합니다.crossing클래식보다 더 잘 작동하는 것.expand.grid(1) 문자열이 요인으로 변환되지 않고 (2) 정렬이 더 직관적이기 때문에 함수:

library(tidyr)

a <- c("ABC", "DEF", "GHI")
b <- c("2012-05-01", "2012-05-02", "2012-05-03", "2012-05-04", "2012-05-05")

crossing(a, b)

# A tibble: 15 x 2
       a          b
   <chr>      <chr>
 1   ABC 2012-05-01
 2   ABC 2012-05-02
 3   ABC 2012-05-03
 4   ABC 2012-05-04
 5   ABC 2012-05-05
 6   DEF 2012-05-01
 7   DEF 2012-05-02
 8   DEF 2012-05-03
 9   DEF 2012-05-04
10   DEF 2012-05-05
11   GHI 2012-05-01
12   GHI 2012-05-02
13   GHI 2012-05-03
14   GHI 2012-05-04
15   GHI 2012-05-05

개요에서 누락된 것은CJtable-package의 함수입니다.사용:

library(data.table)
CJ(a, b, unique = TRUE)

제공:

      a          b
 1: ABC 2012-05-01
 2: ABC 2012-05-02
 3: ABC 2012-05-03
 4: ABC 2012-05-04
 5: ABC 2012-05-05
 6: DEF 2012-05-01
 7: DEF 2012-05-02
 8: DEF 2012-05-03
 9: DEF 2012-05-04
10: DEF 2012-05-05
11: GHI 2012-05-01
12: GHI 2012-05-02
13: GHI 2012-05-03
14: GHI 2012-05-04
15: GHI 2012-05-05

참고: 버전 1.12.2 이후CJ결과 열 이름을 자동으로 지정합니다(여기 및 여기 참조).

버전 1.0.0 이후,tidyr의 자체 버전을 제공합니다.expand.grid()벡터로 작동하는 하위 수준 함수를 사용하여 , 및 의 기존 패밀리를 완성합니다.

와 비교했을 때base::expand.grid():

첫 번째 요소가 가장 빠르게 변화합니다.문자열을 요인으로 변환하지 않습니다.추가 특성을 추가하지 않습니다.데이터 프레임이 아닌 경골을 반환합니다.데이터 프레임을 포함하여 일반화된 벡터를 확장할 수 있습니다.

a <- c("ABC", "DEF", "GHI")
b <- c("2012-05-01", "2012-05-02", "2012-05-03", "2012-05-04", "2012-05-05")

tidyr::expand_grid(a, b)

   a     b         
   <chr> <chr>     
 1 ABC   2012-05-01
 2 ABC   2012-05-02
 3 ABC   2012-05-03
 4 ABC   2012-05-04
 5 ABC   2012-05-05
 6 DEF   2012-05-01
 7 DEF   2012-05-02
 8 DEF   2012-05-03
 9 DEF   2012-05-04
10 DEF   2012-05-05
11 GHI   2012-05-01
12 GHI   2012-05-02
13 GHI   2012-05-03
14 GHI   2012-05-04
15 GHI   2012-05-05

순서 함수를 사용하여 원하는 수의 열을 정렬할 수 있습니다.예를 들어

df <- expand.grid(a,b)
> df
   Var1       Var2
1   ABC 2012-05-01
2   DEF 2012-05-01
3   GHI 2012-05-01
4   ABC 2012-05-02
5   DEF 2012-05-02
6   GHI 2012-05-02
7   ABC 2012-05-03
8   DEF 2012-05-03
9   GHI 2012-05-03
10  ABC 2012-05-04
11  DEF 2012-05-04
12  GHI 2012-05-04
13  ABC 2012-05-05
14  DEF 2012-05-05
15  GHI 2012-05-05

> df[order( df[,1], df[,2] ),] 
   Var1       Var2
1   ABC 2012-05-01
4   ABC 2012-05-02
7   ABC 2012-05-03
10  ABC 2012-05-04
13  ABC 2012-05-05
2   DEF 2012-05-01
5   DEF 2012-05-02
8   DEF 2012-05-03
11  DEF 2012-05-04
14  DEF 2012-05-05
3   GHI 2012-05-01
6   GHI 2012-05-02
9   GHI 2012-05-03
12  GHI 2012-05-04
15  GHI 2012-05-05`

기본 R에서 병합(), cbind() 및 expand.grid()를 시도할 수 있습니다.

a <- seq(1E4)
b <- c("2012-05-01", "2012-05-02", "2012-05-03", "2012-05-04", "2012-05-05")

 microbenchmark(
  "merge (1)" = mmm <- as.matrix(merge(a, b)),
  "diy (2)"   = {ccc <- cbind( rep(a, length(b)),
                               b[rep(seq_along(b), each = length(a))]
                        )
                },
 "diy R (3)"  = {ccc <- cbind( a,
                               b[rep(seq_along(b), each = length(a))]
                        )
                },
  "grid (4)"  = ggg <- expand.grid(a, b),
  times       = 2
)

산출량.

Unit: milliseconds
      expr      min       lq     mean   median       uq      max neval
 merge (1) 863.3100 863.3100 888.6573 888.6573 914.0046 914.0046     2
   diy (2) 117.1912 117.1912 142.1394 142.1394 167.0875 167.0875     2
 diy R (3)  34.9320  34.9320  49.4119  49.4119  63.8918  63.8918     2
  grid (4)  45.1876  45.1876  46.1592  46.1592  47.1308  47.1308     2

사용할 수 있습니다.rep기본 R 데이터 프레임이 재활용한다는 사실:

data.frame(
  a = rep(a, each = length(b)),
  b = b
)

언급URL : https://stackoverflow.com/questions/11388359/unique-combination-of-all-elements-from-two-or-more-vectors

반응형