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의 기능 목록.그것은 재귀적이기 때문에, 그것은 더 복잡한 상황들을 처리할 것입니다.mapply는 '첫 번째'에 없는 '초'의 항목을 무시함으로써 일치하지 않는 이름 상황을 처리합니다.
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
네, 알아요. 아마도 가장 논리적인 병합은 아니지만 복잡한 병렬 루프를 사용하여 보다 맞춤화된 작업을 수행해야 했습니다..combinefunction for, 그래서 저는 이 몬스터를 썼습니다 :-)
merged = map(names(first), ~c(first[[.x]], second[[.x]])
merged = set_names(merged, names(first))
purrr을 사용.또한 목록이 순서에 맞지 않는 문제도 해결합니다.
일반적으로 할 수 있는 일은
merge_list <- function(...) by(v<-unlist(c(...)),names(v),base::c)
참고하세요.by()용액은 a를 반환합니다.attributed 리스트, 그래서 다르게 인쇄되겠지만 여전히 리스트가 될 것입니다.하지만 당신은 다음과 같이 속성을 제거할 수 있습니다.attr(x,"_attribute.name_")<-NULL. 사용할 수도 있습니다.aggregate().
우리는 할 수 있습니다.lapply와 함께c(), 사용.setNames출력에 원래 이름을 할당합니다.
setNames(lapply(1:length(first), function(x) c(first[[x]], second[[x]])), names(first))
$a
[1] 1 2
$b
[1] 2 3
$c
[1] 3 4
@Aaron left Stack Overflow 및 @Theo answer에 이어 병합된 목록의 요소는 벡터 형식입니다.c. 그러나 행과 열을 바인딩하려면rbind그리고.cbind.
merged = map(names(first), ~rbind(first[[.x]], second[[.x]])
merged = set_names(merged, names(first))
dplyr을 사용하여 이 행이 동일한 이름을 사용하는 명명된 목록에 대해 작동함을 발견했습니다.
as.list(bind_rows(first, second))
언급URL : https://stackoverflow.com/questions/9519543/merge-two-lists-in-r
'programing' 카테고리의 다른 글
| XML 문자열에서 XML 문서로 (0) | 2023.10.02 |
|---|---|
| __builtin_clz 구현 (0) | 2023.10.02 |
| Responsive 메뉴로 신체 스크롤 방지 방법 (0) | 2023.10.02 |
| Python에서 lxml 라이브러리를 사용하여 xml 파일 쓰기 (0) | 2023.10.02 |
| 오류 2003(HY000):MySQL 서버에 연결할 수 없음 (111) (0) | 2023.10.02 |