programing

목록 내의 여러 data.frames를 동시에 Marge합니다.

topblog 2023. 4. 23. 09:58
반응형

목록 내의 여러 data.frames를 동시에 Marge합니다.

dataframes data . frames 、 습습이습습습 。는 각 변수(이것을 data.frame이라고 하고 있다는 입니다."var1" ★★★★★★★★★★★★★★★★★」"var2"을 사용법) data.frames는 .frames로 하면 됩니다.rbind프라이어의 RBIND입니다.fill이면 충분하지만 이 데이터는 그렇지 않습니다.

냐하 because는merge명령어는 2개의 데이터에서만 작동합니다.프레임, 아이디어를 얻기 위해 인터넷에 접속했습니다.R 2.7.2에서는 완벽하게 동작하는 것을 여기서 구입했습니다.그때 제가 가지고 있던 것입니다.

merge.rec <- function(.list, ...){
    if(length(.list)==1) return(.list[[1]])
    Recall(c(list(merge(.list[[1]], .list[[2]], ...)), .list[-(1:2)]), ...)
}

이 함수를 다음과 같이 부릅니다.

df <- merge.rec(my.list, by.x = c("var1", "var2"), 
                by.y = c("var1", "var2"), all = T, suffixes=c("", ""))

그러나 2.11 및 2.12를 포함한 2.7.2 이후의 R 버전에서는 이 코드가 실패하고 다음 오류가 발생합니다.

Error in match.names(clabs, names(xi)) : 
  names do not match previous names

(이 에러에 대한 다른 참조는, 해결 방법이 없는 다른 장소에서도 볼 수 있습니다).

이 문제를 해결할 방법이 있을까요?

다른 질문에서는 구체적으로 R의 dplyr을 사용하여 여러 왼쪽 조인을 실행하는 방법을 묻습니다.이 질문은 이 질문의 중복으로 마크되어 있기 때문에 다음 3개의 샘플 데이터 프레임을 사용하여 답변합니다.

x <- data.frame(i = c("a","b","c"), j = 1:3, stringsAsFactors=FALSE)
y <- data.frame(i = c("b","c","d"), k = 4:6, stringsAsFactors=FALSE)
z <- data.frame(i = c("c","d","a"), l = 7:9, stringsAsFactors=FALSE)

답변은 3개의 섹션으로 나누어져 있으며, 3개의 다른 방법으로 Marge를 실행할 수 있습니다. '우리'를 예요.purrrtidyverse 패키지를 이미 사용하고 있다면 방법이 있습니다.아래의 비교를 위해 동일한 샘플 데이터 집합을 사용하는 기본 R 버전을 찾을 수 있습니다.


① ) 1 1 1 1 1 1 1 1 1 1 1 1로 reduce purrr★★★★★★★★★★★★★★★★★★:

purrr는 「」를 합니다.reduce"CHANGE: "CHANGE:

library(tidyverse)
list(x, y, z) %>% reduce(left_join, by = "i")
#  A tibble: 3 x 4
#  i       j     k     l
#  <chr> <int> <int> <int>
# 1 a      1    NA     9
# 2 b      2     4    NA
# 3 c      3     5     7

에도 '하다, 하다, 하다, 하다' 의 조인을 할 수. ★★★★★★★★★★★★★★★★★,full_join ★★★★★★★★★★★★★★★★★」inner_join:

list(x, y, z) %>% reduce(full_join, by = "i")
# A tibble: 4 x 4
# i       j     k     l
# <chr> <int> <int> <int>
# 1 a     1     NA     9
# 2 b     2     4      NA
# 3 c     3     5      7
# 4 d     NA    6      8

list(x, y, z) %>% reduce(inner_join, by = "i")
# A tibble: 1 x 4
# i       j     k     l
# <chr> <int> <int> <int>
# 1 c     3     5     7

2)dplyr::left_join() R ' ' ' ' 'R'의Reduce():

list(x,y,z) %>%
    Reduce(function(dtf1,dtf2) left_join(dtf1,dtf2,by="i"), .)

#   i j  k  l
# 1 a 1 NA  9
# 2 b 2  4 NA
# 3 c 3  5  7

R 3) Rmerge() R ' ' ' ' 'R'의Reduce():

비교를 위해 Charles의 답변을 바탕으로 왼쪽 조인의 기본 R 버전을 보여 줍니다.

 Reduce(function(dtf1, dtf2) merge(dtf1, dtf2, by = "i", all.x = TRUE),
        list(x,y,z))
#   i j  k  l
# 1 a 1 NA  9
# 2 b 2  4 NA
# 3 c 3  5  7

감소로 인해 이 작업이 상당히 쉬워집니다.

merged.data.frame = Reduce(function(...) merge(..., all=T), list.of.data.frames)

다음은 몇 가지 모의 데이터를 사용한 완전한 예입니다.

set.seed(1)
list.of.data.frames = list(data.frame(x=1:10, a=1:10), data.frame(x=5:14, b=11:20), data.frame(x=sample(20, 10), y=runif(10)))
merged.data.frame = Reduce(function(...) merge(..., all=T), list.of.data.frames)
tail(merged.data.frame)
#    x  a  b         y
#12 12 NA 18        NA
#13 13 NA 19        NA
#14 14 NA 20 0.4976992
#15 15 NA NA 0.7176185
#16 16 NA NA 0.3841037
#17 19 NA NA 0.3800352

여기 이 데이터를 사용하여 복제한 예가 있습니다.my.list:

merged.data.frame = Reduce(function(...) merge(..., by=match.by, all=T), my.list)
merged.data.frame[, 1:12]

#  matchname party st district chamber senate1993 name.x v2.x v3.x v4.x senate1994 name.y
#1   ALGIERE   200 RI      026       S         NA   <NA>   NA   NA   NA         NA   <NA>
#2     ALVES   100 RI      019       S         NA   <NA>   NA   NA   NA         NA   <NA>
#3    BADEAU   100 RI      032       S         NA   <NA>   NA   NA   NA         NA   <NA>

주의: 님의 인 것 : : 것 note것은 note note note note note note note note note note note note note note note note note note note note note note note note note note note 。merge문제는 (비일치 이름이 중복되는 것을 처리하기 위해) 서픽스를 추가하는 것이 실제로 그것들을 고유하게 만드는지를 확인할 수 없다는 것입니다.에서는 어어시음음, 음음음음음음음음 at at at at at at at at at at at at at at at at at at at를 사용합니다.[.data.frame어느 쪽인가 하면 make.unique 즉 ""의 이 됩니다.rbind패하하다

# first merge will end up with 'name.x' & 'name.y'
merge(my.list[[1]], my.list[[2]], by=match.by, all=T)
# [1] matchname    party        st           district     chamber      senate1993   name.x      
# [8] votes.year.x senate1994   name.y       votes.year.y
#<0 rows> (or 0-length row.names)
# as there is no clash, we retain 'name.x' & 'name.y' and get 'name' again
merge(merge(my.list[[1]], my.list[[2]], by=match.by, all=T), my.list[[3]], by=match.by, all=T)
# [1] matchname    party        st           district     chamber      senate1993   name.x      
# [8] votes.year.x senate1994   name.y       votes.year.y senate1995   name         votes.year  
#<0 rows> (or 0-length row.names)
# the next merge will fail as 'name' will get renamed to a pre-existing field.

수 있는 은 중복된 필드의 이름 이 있음)을 최대 5까지 그대로 입니다.merge. 예:

my.list2 = Map(function(x, i) setNames(x, ifelse(names(x) %in% match.by,
      names(x), sprintf('%s.%d', names(x), i))), my.list, seq_along(my.list))

merge/Reduce정상적으로 동작합니다.

다음을 사용하여 할 수 있습니다.merge_all에서reshape패키지.매개 변수를 다음에 전달할 수 있습니다.merge사용방법...논쟁

reshape::merge_all(list_of_dataframes, ...)

다음은 데이터 프레임을 병합하는 다양한 방법에 대한 우수한 리소스입니다.

{powerjoin}을(를) 사용할 수 있습니다.

승인된 답변에서 샘플 데이터 차용:

x <- data.frame(i = c("a","b","c"), j = 1:3, stringsAsFactors=FALSE)
y <- data.frame(i = c("b","c","d"), k = 4:6, stringsAsFactors=FALSE)
z <- data.frame(i = c("c","d","a"), l = 7:9, stringsAsFactors=FALSE)

library(powerjoin)
power_full_join(list(x,y,z), by = "i")
#>   i  j  k  l
#> 1 a  1 NA  9
#> 2 b  2  4 NA
#> 3 c  3  5  7
#> 4 d NA  6  8

power_left_join(list(x,y,z), by = "i")
#>   i j  k  l
#> 1 a 1 NA  9
#> 2 b 2  4 NA
#> 3 c 3  5  7

데이터 프레임에서 시작하여 데이터 프레임 목록에 가입할 수도 있습니다.


power_full_join(x, list(y,z), by = "i")
#>   i  j  k  l
#> 1 a  1 NA  9
#> 2 b  2  4 NA
#> 3 c  3  5  7
#> 4 d NA  6  8

이를 위해 재귀를 사용할 수 있습니다.다음 사항을 검증하지는 않았지만 올바른 정보를 얻을 수 있을 것입니다.

MergeListOfDf = function( data , ... )
{
    if ( length( data ) == 2 ) 
    {
        return( merge( data[[ 1 ]] , data[[ 2 ]] , ... ) )
    }    
    return( merge( MergeListOfDf( data[ -1 ] , ... ) , data[[ 1 ]] , ... ) )
}

@PaulRougieux의 데이터 예제를 재사용합니다.

x <- data_frame(i = c("a","b","c"), j = 1:3)
y <- data_frame(i = c("b","c","d"), k = 4:6)
z <- data_frame(i = c("c","d","a"), l = 7:9)

여기 간단한 솔루션이 있습니다.purrr그리고.tidyr

library(tidyverse)

 list(x, y, z) %>% 
  map_df(gather, key=key, value=value, -i) %>% 
  spread(key, value)

공통 ID 열이 없는 데이터 프레임 목록이 있습니다.
많은 DFS에서 데이터가 누락되었습니다.Null 값이 있습니다.데이터 프레임은 테이블 함수를 사용하여 생성되었습니다.축소, 병합, rbind, rbind.가득 채워도 내 목표에는 도움이 되지 않았다.저의 목표는 누락된 데이터와 공통 ID 열과는 무관하게 이해하기 쉬운 병합 데이터 프레임을 생성하는 것이었습니다.

그래서 저는 다음과 같은 기능을 만들었습니다.이 기능이 누군가를 도울 수 있을지도 몰라.

##########################################################
####             Dependencies                        #####
##########################################################

# Depends on Base R only

##########################################################
####             Example DF                          #####
##########################################################

# Example df
ex_df           <- cbind(c( seq(1, 10, 1), rep("NA", 0), seq(1,10, 1) ), 
                         c( seq(1, 7, 1),  rep("NA", 3), seq(1, 12, 1) ), 
                         c( seq(1, 3, 1),  rep("NA", 7), seq(1, 5, 1), rep("NA", 5) ))

# Making colnames and rownames
colnames(ex_df) <- 1:dim(ex_df)[2]
rownames(ex_df) <- 1:dim(ex_df)[1]

# Making an unequal list of dfs, 
# without a common id column
list_of_df      <- apply(ex_df=="NA", 2, ( table) )

그것은 그 기능을 따르고 있다.

##########################################################
####             The function                        #####
##########################################################


# The function to rbind it
rbind_null_df_lists <- function ( list_of_dfs ) {
  length_df     <- do.call(rbind, (lapply( list_of_dfs, function(x) length(x))))
  max_no        <- max(length_df[,1])
  max_df        <- length_df[max(length_df),]
  name_df       <- names(length_df[length_df== max_no,][1])
  names_list    <- names(list_of_dfs[ name_df][[1]])

  df_dfs <- list()
  for (i in 1:max_no ) {

    df_dfs[[i]]            <- do.call(rbind, lapply(1:length(list_of_dfs), function(x) list_of_dfs[[x]][i]))

  }

  df_cbind               <- do.call( cbind, df_dfs )
  rownames( df_cbind )   <- rownames (length_df)
  colnames( df_cbind )   <- names_list

  df_cbind

}

예제의 실행

##########################################################
####             Running the example                 #####
##########################################################

rbind_null_df_lists ( list_of_df )

바이너리 함수를 다중 파라미터 함수로 변환하기 위해 사용할 수 있는 범용 래퍼입니다.이 솔루션의 장점은 매우 일반적이며 모든 이진 함수에 적용할 수 있다는 것입니다.한 번만 하면 돼요.어디에나 적용해도 돼요

아이디어를 시연하기 위해 간단한 재귀로 구현합니다.물론 기능 패러다임에 대한 R의 훌륭한 지원으로부터 혜택을 받을 수 있는 보다 우아한 방법으로 구현할 수 있습니다.

fold_left <- function(f) {
return(function(...) {
    args <- list(...)
    return(function(...){
    iter <- function(result,rest) {
        if (length(rest) == 0) {
            return(result)
        } else {
            return(iter(f(result, rest[[1]], ...), rest[-1]))
        }
    }
    return(iter(args[[1]], args[-1]))
    })
})}

그런 다음 바이너리 함수를 사용하여 첫 번째 괄호 안에 위치 파라미터(일반적으로 data.frames)와 두 번째 괄호 안에 이름 있는 파라미터(예:by = ★★★★★★★★★★★★★★★★★」suffix =이름 있는 파라미터가 없는 경우 두 번째 괄호는 비워 둡니다.

merge_all <- fold_left(merge)
merge_all(df1, df2, df3, df4, df5)(by.x = c("var1", "var2"), by.y = c("var1", "var2"))

left_join_all <- fold_left(left_join)
left_join_all(df1, df2, df3, df4, df5)(c("var1", "var2"))
left_join_all(df1, df2, df3, df4, df5)()

dfs 목록이 있고 열에 "ID"가 포함되어 있지만 일부 목록에서 ID가 누락된 경우 이 버전의 Reduce/Merge를 사용하여 누락된 행 ID 또는 레이블의 여러 DFS에 가입할 수 있습니다.

Reduce(function(x, y) merge(x=x, y=y, by="V1", all.x=T, all.y=T), list_of_dfs)

언급URL : https://stackoverflow.com/questions/8091303/simultaneously-merge-multiple-data-frames-in-a-list

반응형