R에서 두 목록 병합
두 개의 목록이 있습니다
first = list(a = 1, b = 2, c = 3)
second = list(a = 2, b = 3, c = 4)
 
이 두 목록을 병합하여 최종 제품이
$a
[1] 1 2
$b
[1] 2 3
$c
[1] 3 4
 
이를 수행하는 간단한 기능이 있습니까?
예에서와 같이 목록의 구조가 항상 동일한 경우 더 간단한 해결책은 다음과 같습니다.
mapply(c, first, second, SIMPLIFY=FALSE)
이것은 Sarkar의 modifyList 함수를 매우 간단하게 수정 한 것입니다. 재귀 적이기 때문에 더 복잡한 상황 mapply을 처리하고, 'first'가 아닌 'second'의 항목을 무시하여 일치하지 않는 이름 상황을 처리합니다.
appendList <- function (x, val) 
{
    stopifnot(is.list(x), is.list(val))
    xnames <- names(x)
    for (v in names(val)) {
        x[[v]] <- if (v %in% xnames && is.list(x[[v]]) && is.list(val[[v]])) 
            appendList(x[[v]], val[[v]])
        else c(x[[v]], val[[v]])
    }
    x
}
> appendList(first,second)
$a
[1] 1 2
$b
[1] 2 3
$c
[1] 3 4
다음은 두 가지 옵션입니다.
both <- list(first, second)
n <- unique(unlist(lapply(both, names)))
names(n) <- n
lapply(n, function(ni) unlist(lapply(both, `[[`, ni)))
 
두 번째는 구조가 동일한 경우에만 작동합니다.
apply(cbind(first, second),1,function(x) unname(unlist(x)))
 
둘 다 원하는 결과를 제공합니다.
여기에 @Andrei의 답변을 기반으로 작성했지만 우아함 / 단순함이없는 코드가 있습니다. 장점은 더 복잡한 재귀 병합을 허용하고 연결되어야하는 요소와 다음 rbind과 방금 연결된 요소간에 차이가 있다는 것 입니다 c.
# Decided to move this outside the mapply, not sure this is 
# that important for speed but I imagine redefining the function
# might be somewhat time-consuming
mergeLists_internal <- function(o_element, n_element){
  if (is.list(n_element)){
    # Fill in non-existant element with NA elements
    if (length(n_element) != length(o_element)){
      n_unique <- names(n_element)[! names(n_element) %in% names(o_element)]
      if (length(n_unique) > 0){
        for (n in n_unique){
          if (is.matrix(n_element[[n]])){
            o_element[[n]] <- matrix(NA, 
                                     nrow=nrow(n_element[[n]]), 
                                     ncol=ncol(n_element[[n]]))
          }else{
            o_element[[n]] <- rep(NA, 
                                  times=length(n_element[[n]]))
          }
        }
      }
      o_unique <- names(o_element)[! names(o_element) %in% names(n_element)]
      if (length(o_unique) > 0){
        for (n in o_unique){
          if (is.matrix(n_element[[n]])){
            n_element[[n]] <- matrix(NA, 
                                     nrow=nrow(o_element[[n]]), 
                                     ncol=ncol(o_element[[n]]))
          }else{
            n_element[[n]] <- rep(NA, 
                                  times=length(o_element[[n]]))
          }
        }
      }
    }  
    # Now merge the two lists
    return(mergeLists(o_element, 
                      n_element))
  }
  if(length(n_element)>1){
    new_cols <- ifelse(is.matrix(n_element), ncol(n_element), length(n_element))
    old_cols <- ifelse(is.matrix(o_element), ncol(o_element), length(o_element))
    if (new_cols != old_cols)
      stop("Your length doesn't match on the elements,",
           " new element (", new_cols , ") !=",
           " old element (", old_cols , ")")
  }
  return(rbind(o_element, 
               n_element, 
               deparse.level=0))
  return(c(o_element, 
           n_element))
}
mergeLists <- function(old, new){
  if (is.null(old))
    return (new)
  m <- mapply(mergeLists_internal, old, new, SIMPLIFY=FALSE)
  return(m)
}
 
내 예는 다음과 같습니다.
v1 <- list("a"=c(1,2), b="test 1", sublist=list(one=20:21, two=21:22))
v2 <- list("a"=c(3,4), b="test 2", sublist=list(one=10:11, two=11:12, three=1:2))
mergeLists(v1, v2)
 
결과는 다음과 같습니다.
$a
     [,1] [,2]
[1,]    1    2
[2,]    3    4
$b
[1] "test 1" "test 2"
$sublist
$sublist$one
     [,1] [,2]
[1,]   20   21
[2,]   10   11
$sublist$two
     [,1] [,2]
[1,]   21   22
[2,]   11   12
$sublist$three
     [,1] [,2]
[1,]   NA   NA
[2,]    1    2
 
네, 압니다-아마도 가장 논리적 인 병합은 아니지만 더 맞춤화 된 .combine함수 를 생성해야하는 복잡한 병렬 루프가 있으므로이 괴물을 작성했습니다 :-)
일반적으로
merge_list <- function(...) by(v<-unlist(c(...)),names(v),base::c)
 
점을 유의 by()솔루션은 반환 attribute이 다르게 인쇄됩니다,하지만 여전히 목록 수 있도록, D 목록을. 그러나 .NET으로 속성을 제거 할 수 있습니다 attr(x,"_attribute.name_")<-NULL. 당신은 아마도 사용할 수 있습니다 aggregate().
참고URL : https://stackoverflow.com/questions/9519543/merge-two-lists-in-r
'developer tip' 카테고리의 다른 글
| size_t의 최대 값을 찾는 이식 가능한 방법은 무엇입니까? (0) | 2020.10.30 | 
|---|---|
| 사용자가 스크롤하고 있는지 감지 (0) | 2020.10.30 | 
| 챗봇 개발을위한 튜토리얼이 있습니까? (0) | 2020.10.29 | 
| angularjs ui-router의 상태간에 $ scope 데이터를 공유하려면 어떻게해야합니까? (0) | 2020.10.29 | 
| C ++ std :: ref (T)와 T &의 차이점은 무엇입니까? (0) | 2020.10.29 |