R의 여러 목록에서 다중 요소 인덱스의 모든 조합을 "결합"하는 더 좋은 방법은 무엇입니까?

산림 학자

각각 여러 인덱스 내에서 여러 하위 요소의 가변 번호를 포함하는 두 개의 목록이 있다고 가정합니다.

list.a <- list(c("a","b","c"), c("x", "y", "z"))
list.b <- list(c("d", "e", "f","g"), c("m", "n"))
  • 결과 :

    > list.a
    [[1]]
    [1] "a" "b" "c"
    
    [[2]]
    [1] "x" "y" "z"
    

    > list.b
    [[1]]
    [1] "d" "e" "f" "g" "h"
    
    [[2]]
    [1] "m" "n" 
    

각 목록의 해당 인덱스에서 하위 요소의 콤보재귀 적으로 액세스하는 방법은 무엇입니까?

  • 예를 들어 첫 번째 인덱스에 대해 ad, ae, af, ag, bd, be, ... 등의 콤보에 액세스하고 각각의 두 번째 인덱스에서 xm, xn, ym, yn, zm 및 zn에 액세스하려고합니다. 명부.

    [[1]]
     [1] "a d" "a e" "a f" "a g" "b d" "b e" "b f" "b g" "c d" "c e" "c f" "c g"
    
    [[2]]
    [1] "x m" "x n" "y m" "y n" "z m" "z n"
    

mapply 각 목록에서 여러 하위 요소가있을 때 작동하지 않는 것 같습니다 (특히 요소 수가 두 목록에서 같지 않은 경우).

> mapply(paste,list.a,list.b)
[[1]]
[1] "a d" "b e" "c f" "a g"

[[2]]
[1] "x m" "y n" "z m"
  • 조합의 절반을 건너 뛰고 대신 두 목록 중 더 짧은 목록 만 재활용합니다. 두 목록에서 공유 인덱스 내의 모든 조합 을 결합하고 싶습니다 .

for루프를 사용할 수도 있습니다 ... :

list.d <- list()
for(i in 1:length(list.a)) {
  list.c <- list()
  list.d[[i]] <- {
    for(j in list.a[[i]]) {
      for(k in list.b[[i]]) {
       list.c <- c(list.c, paste(j, k))
      }
    }
    unlist(list.c)
    }
}

원하는 결과를 생성합니다.

> list.d
[[1]]
 [1] "a d" "a e" "a f" "a g" "b d" "b e" "b f" "b g" "c d" "c e" "c f" "c g"

[[2]]
[1] "x m" "x n" "y m" "y n" "z m" "z n"

...하지만 루프는 기껏해야 지저분하고 거대한 목록으로 상당히 느려집니다.

이 작업을 수행하는 더 좋은 방법이 있습니까?

  • 특히, apply이 작업을보다 효율적으로 수행 할 수있는 기능 을 사용하기위한 특별한 기능이나 접근 방식 이 있습니까?


<신청>

(이 부분은 질문에 답하는 데 필요하지 않지만 사용 컨텍스트 / 확장을 제공합니다) :

궁금한 사람들을 위해 이것을 확장 paste()하고 대신 data.frame에서 사용하고 싶습니다.

  • 예를 들면 :

    각각 여러 하위 요소가있는 여러 인덱스를 포함하는 두 개의 목록이 있다고 가정합니다.

    l1 <- list(c(1933:1935),c(1950:1954), c(2012:2013))  #groups of years
    l2 <- list(c(19:21),c(19:24),c(22:26))               #groups of plot numbers
    

    또한 다음과 같은 data.frame이 있다고 가정 해 보겠습니다.

    dat <- data.frame(plot = rep(1:30,81), year = rep(1933:2013, each = 30), area = sample(270))
    
    > head(dat)
      plot year area
    1    1 1933  137
    2    2 1933   72
    3    3 1933  136
    4    4 1933  187
    5    5 1933  206
    6    6 1933   74
    

    일치하는 각 목록 인덱스에 대한 (연도) 및 (플롯) l3의 모든 조합에 대한 합계 영역을 포함 하는 새 목록 (이라고 함 ) 을 만들고 싶습니다 .l1l2

    • 예를 들어, [[1]]결과 목록의 결과 는 1933, 1934 1935 각각에 대한 19, 20 21 플롯의 면적 합계입니다 .

      에 대한 결과는 [[2]]1950 년부터 1954 년까지의 각 기간에 대해 19-24 번 구획에 대한 합계 영역이됩니다.

Psidom

필요한 expand.grid경우 다음 용도로 사용됩니다.

제공된 벡터 또는 요인의 모든 조합에서 데이터 프레임을 만듭니다.

사용 do.call(paste, ...)은 데이터 프레임의 모든 열을 함께 붙여 넣는 것입니다.

Map(function(a,b) do.call(paste, expand.grid(a,b)), list.a, list.b)

#[[1]]
# [1] "a d" "b d" "c d" "a e" "b e" "c e" "a f" "b f" "c f" "a g" "b g" "c g"

#[[2]]
#[1] "x m" "y m" "z m" "x n" "y n" "z n"

질문의 두 번째 부분에서는 연도별로 데이터 프레임을 부분 집합하고 먼저 플로팅 한 다음 rowsum을 사용하여 연도 별로 면적 을 집계 할 수 있습니다 .

Map(function(years, plots) {
    with(subset(dat, plot %in% plots & year %in% years), rowsum(area, year))
}, l1, l2)

[[1]]
     [,1]
1933  257
1934  398
1935  640

[[2]]
     [,1]
1950  950
1951  457
1952  601
1953 1202
1954 1148

[[3]]
     [,1]
2012  736
2013  497

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관