2017-12-13 1 views
0

5 개의 데이터 프레임과 그 중 하나의 열이 동일한 타임 스탬프 ("연도")를 기반으로한다고 가정하십시오. 각각은 아마도 다른 수의 행과 열을 가질 수 있지만, 각각은 year라는 첫 번째 열을 가지고 있습니다. 다른 시작과 끝에서 다른 연도가 있으므로 모든 데이터 프레임 중에서 시작일이나 종료일이 공통된 것은 아닙니다. 데이터를 수집 한 연도를 기준으로 모든 데이터 프레임을 하나로 합치기를 원합니다 (즉, 특정 연도의 한 매트릭스에서 수집 된 데이터는 같은 해 다른 데이터 프레임의 데이터와 일치 함). 해당 연도가없는 데이터 프레임의 경우 해당 공백을 NA로 채 웁니다.데이터 프레임을 "공통 열의 다른 수의 요소와 공통 인 하나의 열 이름"과 하나로 결합하십시오.

어떻게 데이터를 정렬하여 하나의 데이터 프레임으로 결합 할 수 있습니까?

이 인수를 위해 가정, 우리는 다음과 같은 dataframes 있습니다

M1 <- data.frame(year=2000:2010, v1=16:26, v2=25:35) 
M1; dim(M1) # 11x3 
M2 <- data.frame(year=2005:2018, v3=6:19, v4=5:18, v5=3:16) 
M2; dim(M2) #14x4 
M3 <- data.frame(year=2002:2016, v3=3:17, v6=2:16, v7=0:14) 
M3; dim(M3) # 15x4 
M4 <- data.frame(year=2008:2020, v3=9:21, v6=8:20, v8=6:18) 
M4; dim(M4) # 13x4 
M5 <- data.frame(year=2018:2020, v9=19:21, v10=18:20, v11=16:18, v12=29:31) 
M5; dim(M5) # 3x5 

참고 : 매우 비슷한 질문이 "명확하지 않다"추론하여 다른 사용자가 요청하고, 폐쇄되었다. 나는 그의 질문을 깔끔하게 정리했다.

답변

3

나는 full_join 명령을 dplyr으로 사용하는 것이 더 효율적이라고 생각합니다. 새 데이터 프레임을 조인해야 할 때마다 full_join을 사용하거나 순차적으로 작동하는 reduce 함수 내에서 한 번 사용하십시오.아래의 두 가지 방법을 참조 :

# create example datasets 
M1 <- data.frame(year=2000:2010, v1=16:26, v2=25:35) 
M2 <- data.frame(year=2005:2018, v3=6:19, v4=5:18, v5=3:16) 
M3 <- data.frame(year=2002:2016, v3=3:17, v6=2:16, v7=0:14) 
M4 <- data.frame(year=2008:2020, v3=9:21, v6=8:20, v8=6:18) 
M5 <- data.frame(year=2018:2020, v9=19:21, v10=18:20, v11=16:18, v12=29:31) 

첫 번째 방법 :

library(dplyr) 

# use the full_join command 
# you have to "manually" use a full_join command for every new dataset you want to join 
full_join(M1, M2, by="year") %>% 
    full_join(M3, by="year") %>% 
    full_join(M4, by="year") %>% 
    full_join(M5, by="year") 

# year v1 v2 v3.x v4 v5 v3.y v6.x v7 v3 v6.y v8 v9 v10 v11 v12 
# 1 2000 16 25 NA NA NA NA NA NA NA NA NA NA NA NA NA 
# 2 2001 17 26 NA NA NA NA NA NA NA NA NA NA NA NA NA 
# 3 2002 18 27 NA NA NA 3 2 0 NA NA NA NA NA NA NA 
# 4 2003 19 28 NA NA NA 4 3 1 NA NA NA NA NA NA NA 
# 5 2004 20 29 NA NA NA 5 4 2 NA NA NA NA NA NA NA 
# 6 2005 21 30 6 5 3 6 5 3 NA NA NA NA NA NA NA 
# 7 2006 22 31 7 6 4 7 6 4 NA NA NA NA NA NA NA 
# 8 2007 23 32 8 7 5 8 7 5 NA NA NA NA NA NA NA 
# 9 2008 24 33 9 8 6 9 8 6 9 8 6 NA NA NA NA 
# 10 2009 25 34 10 9 7 10 9 7 10 9 7 NA NA NA NA 
# 11 2010 26 35 11 10 8 11 10 8 11 10 8 NA NA NA NA 
# 12 2011 NA NA 12 11 9 12 11 9 12 11 9 NA NA NA NA 
# 13 2012 NA NA 13 12 10 13 12 10 13 12 10 NA NA NA NA 
# 14 2013 NA NA 14 13 11 14 13 11 14 13 11 NA NA NA NA 
# 15 2014 NA NA 15 14 12 15 14 12 15 14 12 NA NA NA NA 
# 16 2015 NA NA 16 15 13 16 15 13 16 15 13 NA NA NA NA 
# 17 2016 NA NA 17 16 14 17 16 14 17 16 14 NA NA NA NA 
# 18 2017 NA NA 18 17 15 NA NA NA 18 17 15 NA NA NA NA 
# 19 2018 NA NA 19 18 16 NA NA NA 19 18 16 19 18 16 29 
# 20 2019 NA NA NA NA NA NA NA NA 20 19 17 20 19 17 30 
# 21 2020 NA NA NA NA NA NA NA NA 21 20 18 21 20 18 31 

두 번째 방법 :

당신은 간단하게 할 수있는
library(purrr) 

# apply full join sequentially to the datasets in your list 
list(M1,M2,M3,M4,M5) %>% 
    reduce(full_join, by="year") 

# year v1 v2 v3.x v4 v5 v3.y v6.x v7 v3 v6.y v8 v9 v10 v11 v12 
# 1 2000 16 25 NA NA NA NA NA NA NA NA NA NA NA NA NA 
# 2 2001 17 26 NA NA NA NA NA NA NA NA NA NA NA NA NA 
# 3 2002 18 27 NA NA NA 3 2 0 NA NA NA NA NA NA NA 
# 4 2003 19 28 NA NA NA 4 3 1 NA NA NA NA NA NA NA 
# 5 2004 20 29 NA NA NA 5 4 2 NA NA NA NA NA NA NA 
# 6 2005 21 30 6 5 3 6 5 3 NA NA NA NA NA NA NA 
# 7 2006 22 31 7 6 4 7 6 4 NA NA NA NA NA NA NA 
# 8 2007 23 32 8 7 5 8 7 5 NA NA NA NA NA NA NA 
# 9 2008 24 33 9 8 6 9 8 6 9 8 6 NA NA NA NA 
# 10 2009 25 34 10 9 7 10 9 7 10 9 7 NA NA NA NA 
# 11 2010 26 35 11 10 8 11 10 8 11 10 8 NA NA NA NA 
# 12 2011 NA NA 12 11 9 12 11 9 12 11 9 NA NA NA NA 
# 13 2012 NA NA 13 12 10 13 12 10 13 12 10 NA NA NA NA 
# 14 2013 NA NA 14 13 11 14 13 11 14 13 11 NA NA NA NA 
# 15 2014 NA NA 15 14 12 15 14 12 15 14 12 NA NA NA NA 
# 16 2015 NA NA 16 15 13 16 15 13 16 15 13 NA NA NA NA 
# 17 2016 NA NA 17 16 14 17 16 14 17 16 14 NA NA NA NA 
# 18 2017 NA NA 18 17 15 NA NA NA 18 17 15 NA NA NA NA 
# 19 2018 NA NA 19 18 16 NA NA NA 19 18 16 19 18 16 29 
# 20 2019 NA NA NA NA NA NA NA NA 20 19 17 20 19 17 30 
# 21 2020 NA NA NA NA NA NA NA NA 21 20 18 21 20 18 31 
+0

아주 좋은 솔루션입니다. 불행히도, 나는 과거 dplyr 패키지에 문제가 있었고 여전히 가지고 있습니다. dplyr (v.0.5.0)을 사용하려고 할 때 "패키지 tidyr과 비 conformal"오류가 발생했습니다. 그 이후로 나는 dplyr을 사용할 수 없었습니다. 위의 솔루션의 단순하고 쉬운 적용은 매우 동정심이 있습니다. –

+0

해당 패키지를 제거한 다음 다시 설치하십시오. 최악의 시나리오는 당신이 직면하는 문제에 대한 또 다른 질문을 만들며 누군가가 당신을 도울 것을 도울 것입니다! :-) 패키지를 사용하지 않는 것은 부끄러운 일입니다. 왜냐하면 어떤 이유로 든 작동하지 않을 수 있기 때문입니다. – AntoniosK

0

1 단계 : 모든 dataframes을 고려하여 최소 및 최대 년을 (를) 찾기 :

min(M1["year"], M2["year"], M3["year"], M4["year"], M5["year"]) # 2000 
max(M1["year"], M2["year"], M3["year"], M4["year"], M5["year"]) # 2020 

2 단계 : 관련의 NA를 펌핑하고, 시작과에서 누락 년 돌보는으로 M5를 통해 M1 확장 끝

M1NA <- rbind(M1, data.frame(year=2011:2020, v1=NA, v2=NA)) 
M1NA 
M2NA <- rbind(data.frame(year=2000:2004, v3=NA, v4=NA, v5=NA), M2, data.frame(year=2019:2020, v3=NA, v4=NA, v5=NA)) 
M2NA 
M3NA <- rbind(data.frame(year=2000:2001, v3=NA, v6=NA, v7=NA), M3, data.frame(year=2017:2020, v3=NA, v6=NA, v7=NA)) 
M3NA 
M4NA <- rbind(data.frame(year=2000:2007, v3=NA, v6=NA, v8=NA), M4) 
M4NA 
M5NA <- rbind(data.frame(year=2000:2017, v9=NA, v10=NA, v11=NA, v12=NA), M5) 
M5NA 

3 단계 : 최종 데이터 프레임에 NA'ed 데이터 프레임 결합. 다른 데이터 프레임에서 연도 열을 반복 할 필요가 없으므로 삭제하십시오. 행렬의 경우

CombinedFrame <- cbind(M1NA, M2NA[-1], M3NA[-1], M4NA[-1], M5NA[-1]) 
CombinedFrame 

, 다음을 수행하십시오

CombinedMatrix <- as.matrix(sapply(CombinedFrame, as.numeric)) 
CombinedMatrix 
CombinedMatrix <- matrix(as.numeric(unlist(CombinedFrame)),nrow=nrow(CombinedFrame)) 
CombinedMatrix 

참고 :
다음과 같은 방법 중 하나로 행렬에 결과 dataframe 변환 위의 변환이 계정에 존재의 가능성을

이렇게하면 다음과 같이됩니다 (원하는 경우).

 year v1 v2 v3 v4 v5 v3 v6 v7 v3 v6 v8 v9 v10 v11 v12 
[1,] 2000 16 25 NA NA NA NA NA NA NA NA NA NA NA NA NA 
[2,] 2001 17 26 NA NA NA NA NA NA NA NA NA NA NA NA NA 
[3,] 2002 18 27 NA NA NA 3 2 0 NA NA NA NA NA NA NA 
[4,] 2003 19 28 NA NA NA 4 3 1 NA NA NA NA NA NA NA 
[5,] 2004 20 29 NA NA NA 5 4 2 NA NA NA NA NA NA NA 
[6,] 2005 21 30 6 5 3 6 5 3 NA NA NA NA NA NA NA 
[7,] 2006 22 31 7 6 4 7 6 4 NA NA NA NA NA NA NA 
[8,] 2007 23 32 8 7 5 8 7 5 NA NA NA NA NA NA NA 
[9,] 2008 24 33 9 8 6 9 8 6 9 8 6 NA NA NA NA 
[10,] 2009 25 34 10 9 7 10 9 7 10 9 7 NA NA NA NA 
[11,] 2010 26 35 11 10 8 11 10 8 11 10 8 NA NA NA NA 
[12,] 2011 NA NA 12 11 9 12 11 9 12 11 9 NA NA NA NA 
[13,] 2012 NA NA 13 12 10 13 12 10 13 12 10 NA NA NA NA 
[14,] 2013 NA NA 14 13 11 14 13 11 14 13 11 NA NA NA NA 
[15,] 2014 NA NA 15 14 12 15 14 12 15 14 12 NA NA NA NA 
[16,] 2015 NA NA 16 15 13 16 15 13 16 15 13 NA NA NA NA 
[17,] 2016 NA NA 17 16 14 17 16 14 17 16 14 NA NA NA NA 
[18,] 2017 NA NA 18 17 15 NA NA NA 18 17 15 NA NA NA NA 
[19,] 2018 NA NA 19 18 16 NA NA NA 19 18 16 19 18 16 29 
[20,] 2019 NA NA NA NA NA NA NA NA 20 19 17 20 19 17 30 
[21,] 2020 NA NA NA NA NA NA NA NA 21 20 18 21 20 18 31 
+0

아니! 'CombinedFrame'은 위의 결과와 똑같은 결과를 보였습니다. 데이터 프레임은 같은 이름의 열을 가질 수 있습니다. 참조하십시오 : https://stat.ethz.ch/R-manual/R-devel/library/base/html/colnames.html 여기에, 읽습니다. "...에 대한 문자 집합은 ** (선호) * * 독특한 ...". 그것은 _ 가능하다고 말한다! –

+1

나는 네가 옳다고 생각해. 실용적이고 가능한 두 가지 :-) – AntoniosK

2

, 제공

Reduce(function(x, y)merge(x, y, by = 'year', all = TRUE), mget(ls(pattern = 'M[0-9]+'))) 

,

year v1 v2 v3.x v4 v5 v3.y v6.x v7 v3 v6.y v8 v9 v10 v11 v12 
1 2000 16 25 NA NA NA NA NA NA NA NA NA NA NA NA NA 
2 2001 17 26 NA NA NA NA NA NA NA NA NA NA NA NA NA 
3 2002 18 27 NA NA NA 3 2 0 NA NA NA NA NA NA NA 
4 2003 19 28 NA NA NA 4 3 1 NA NA NA NA NA NA NA 
5 2004 20 29 NA NA NA 5 4 2 NA NA NA NA NA NA NA 
6 2005 21 30 6 5 3 6 5 3 NA NA NA NA NA NA NA 
7 2006 22 31 7 6 4 7 6 4 NA NA NA NA NA NA NA 
8 2007 23 32 8 7 5 8 7 5 NA NA NA NA NA NA NA 
9 2008 24 33 9 8 6 9 8 6 9 8 6 NA NA NA NA 
10 2009 25 34 10 9 7 10 9 7 10 9 7 NA NA NA NA 
11 2010 26 35 11 10 8 11 10 8 11 10 8 NA NA NA NA 
12 2011 NA NA 12 11 9 12 11 9 12 11 9 NA NA NA NA 
13 2012 NA NA 13 12 10 13 12 10 13 12 10 NA NA NA NA 
14 2013 NA NA 14 13 11 14 13 11 14 13 11 NA NA NA NA 
15 2014 NA NA 15 14 12 15 14 12 15 14 12 NA NA NA NA 
16 2015 NA NA 16 15 13 16 15 13 16 15 13 NA NA NA NA 
17 2016 NA NA 17 16 14 17 16 14 17 16 14 NA NA NA NA 
18 2017 NA NA 18 17 15 NA NA NA 18 17 15 NA NA NA NA 
19 2018 NA NA 19 18 16 NA NA NA 19 18 16 19 18 16 29 
20 2019 NA NA NA NA NA NA NA NA 20 19 17 20 19 17 30 
21 2020 NA NA NA NA NA NA NA NA 21 20 18 21 20 18 31 
2

데이터 프레임의 일부 (3210)는 동일한 열 이름을 수행. 따라서 동일한 연도와 열 이름에 대해 다른 값이있을 수 있습니다.

따라서, 나는 모든 데이터 프레임 rbindlist()에 제안하고 사람들은 "복제"할 것 적절한 집계 함수와 melt()dcast()을 사용하여 눈에 보이는 엔트리 :

df_list <- mget(paste0("M", 1:5)) 

library(datat.table) 
rbindlist(df_list, use.names = TRUE, fill = TRUE, idcol = "df")[ 
    , melt(.SD, id.vars = c("df", "year"), na.rm = TRUE)][ 
    , dcast(.SD, year ~ variable, function(x) toString(unique(x)))] 
year v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 
1: 2000 16 25         
2: 2001 17 26         
3: 2002 18 27 3  2 0     
4: 2003 19 28 4  3 1     
5: 2004 20 29 5  4 2     
6: 2005 21 30 6 5 3 5 3     
7: 2006 22 31 7 6 4 6 4     
8: 2007 23 32 8 7 5 7 5     
9: 2008 24 33 9 8 6 8 6 6    
10: 2009 25 34 10 9 7 9 7 7    
11: 2010 26 35 11 10 8 10 8 8    
12: 2011  12 11 9 11 9 9    
13: 2012  13 12 10 12 10 10    
14: 2013  14 13 11 13 11 11    
15: 2014  15 14 12 14 12 12    
16: 2015  16 15 13 15 13 13    
17: 2016  17 16 14 16 14 14    
18: 2017  18 17 15 17 15    
19: 2018  19 18 16 18 16 19 18 16 29 
20: 2019  20  19 17 20 19 17 30 
21: 2020  21  20 18 21 20 18 31 
    year v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 

을 다른 방법으로, 원본 데이터 프레임의 이름을 사용하여 열 이름을 고유하게 만들 수 있습니다.

rbindlist(df_list, use.names = TRUE, fill = TRUE, idcol = "df")[ 
    , melt(.SD, id.vars = c("df", "year"), na.rm = TRUE)][ 
    , dcast(.SD, year ~ paste(variable, df, sep = "_"))] 
year v10_M5 v11_M5 v12_M5 v1_M1 v2_M1 v3_M2 v3_M3 v3_M4 v4_M2 v5_M2 v6_M3 v6_M4 v7_M3 v8_M4 v9_M5 
1: 2000  NA  NA  NA 16 25 NA NA NA NA NA NA NA NA NA NA 
2: 2001  NA  NA  NA 17 26 NA NA NA NA NA NA NA NA NA NA 
3: 2002  NA  NA  NA 18 27 NA  3 NA NA NA  2 NA  0 NA NA 
4: 2003  NA  NA  NA 19 28 NA  4 NA NA NA  3 NA  1 NA NA 
5: 2004  NA  NA  NA 20 29 NA  5 NA NA NA  4 NA  2 NA NA 
6: 2005  NA  NA  NA 21 30  6  6 NA  5  3  5 NA  3 NA NA 
7: 2006  NA  NA  NA 22 31  7  7 NA  6  4  6 NA  4 NA NA 
8: 2007  NA  NA  NA 23 32  8  8 NA  7  5  7 NA  5 NA NA 
9: 2008  NA  NA  NA 24 33  9  9  9  8  6  8  8  6  6 NA 
10: 2009  NA  NA  NA 25 34 10 10 10  9  7  9  9  7  7 NA 
11: 2010  NA  NA  NA 26 35 11 11 11 10  8 10 10  8  8 NA 
12: 2011  NA  NA  NA NA NA 12 12 12 11  9 11 11  9  9 NA 
13: 2012  NA  NA  NA NA NA 13 13 13 12 10 12 12 10 10 NA 
14: 2013  NA  NA  NA NA NA 14 14 14 13 11 13 13 11 11 NA 
15: 2014  NA  NA  NA NA NA 15 15 15 14 12 14 14 12 12 NA 
16: 2015  NA  NA  NA NA NA 16 16 16 15 13 15 15 13 13 NA 
17: 2016  NA  NA  NA NA NA 17 17 17 16 14 16 16 14 14 NA 
18: 2017  NA  NA  NA NA NA 18 NA 18 17 15 NA 17 NA 15 NA 
19: 2018  18  16  29 NA NA 19 NA 19 18 16 NA 18 NA 16 19 
20: 2019  19  17  30 NA NA NA NA 20 NA NA NA 19 NA 17 20 
21: 2020  20  18  31 NA NA NA NA 21 NA NA NA 20 NA 18 21 
    year v10_M5 v11_M5 v12_M5 v1_M1 v2_M1 v3_M2 v3_M3 v3_M4 v4_M2 v5_M2 v6_M3 v6_M4 v7_M3 v8_M4 v9_M5 
관련 문제