데이터 분석을 하다 보면 여기 저기 흩어져 있는 데이터를 특정한 Key를 기준으로 병합해서 분석해야 하는 경우가 매우 많습니다.

 

지난번 포스팅에서는 DataFrame을 pandas의 concat() 함수를 이용해서 합치는 방법, append() 함수를 사용해서 합치는 방법을 소개하였습니다.

 

이번 포스팅에서는 SQL을 사용해서 Database의 Table 들을 Join/Merge 하는 것과 유사하게 Python pandas의 pd.merge() 함수를 사용해서 DataFrame을 Key 기준으로 inner, outer, left, outer join 하여 합치는 방법을 소개하도록 하겠습니다.

 

SQL을 사용하는데 익숙한 분석가라면 매우 쉽고 빠르게 이해하실 수 있을 것입니다. 그리고 Python의 merge() 기능은 메모리 상에서 매우 빠르게 작동함으로 사용하는데 있어 불편함이 덜할 것 같습니다.

 

 

 

 

 

pandas merge 함수 설정값들은 아래와 같이 여러개가 있는데요, 이중에서  'how'와 'on'은 꼭 기억해두셔야 합니다.

 

 

pd.merge(left, right, # merge할 DataFrame 객체 이름
             how='inner', # left, rigth, inner (default), outer
             on=None, # merge의 기준이 되는 Key 변수
             left_on=None, # 왼쪽 DataFrame의 변수를 Key로 사용
             right_on=None, # 오른쪽 DataFrame의 변수를 Key로 사용
             left_index=False, # 만약 True 라면, 왼쪽 DataFrame의 index를 merge Key로 사용
             right_index=False, # 만약 True 라면, 오른쪽 DataFrame의 index를 merge Key로 사용
             sort=True, # merge 된 후의 DataFrame을 join Key 기준으로 정렬
             suffixes=('_x', '_y'), # 중복되는 변수 이름에 대해 접두사 부여 (defaults to '_x', '_y'
             copy=True, # merge할 DataFrame을 복사
             indicator=False) # 병합된 이후의 DataFrame에 left_only, right_only, both 등의 출처를 알 수 있는 부가 정보 변수 추가

 

 

 

먼저, pandas, DataFrame library를 importing 한 후에, 2개의 DataFrame을 만들어보겠습니다.

 

 

In [1]: import pandas as pd


In [2]: from pandas import DataFrame


In [3]: df_left = DataFrame({'KEY': ['K0', 'K1', 'K2', 'K3'],

   ...: 'A': ['A0', 'A1', 'A2', 'A3'],

   ...: 'B': ['B0', 'B1', 'B2', 'B3']})

   ...:


In [4]: df_right = DataFrame({'KEY': ['K2', 'K3', 'K4', 'K5'],

   ...: 'C': ['C2', 'C3', 'C4', 'C5'],

   ...: 'D': ['D2', 'D3', 'D4', 'D5']})

   ...:


In [5]: df_left

Out[5]:

    A   B KEY
0  A0  B0  K0
1  A1  B1  K1
2  A2  B2  K2
3  A3  B3  K3


In [6]: df_right

Out[6]:

    C   D KEY
0  C2  D2  K2
1  C3  D3  K3
2  C4  D4  K4
3  C5  D5  K5

 

 

 

 

 

'how' 의 left, right, inner, outer 별로 위에서 만든 'df_left'와 'df_right' 두 개의 DataFrame을 'KEY' 변수를 기준으로 merge 해보겠습니다.  SQL join에 익숙하신 분이라면 쉽게 이해할 수 있을 것입니다.

 

 

  (1) Merge method : left (SQL join name : LEFT OUTER JOIN)

 

 

In [7]: df_merge_how_left = pd.merge(df_left, df_right,

   ...: how='left',

   ...: on='KEY')

   ...:


In [8]: df_merge_how_left

Out[8]:

     A   B   KEY   C     D
0  A0  B0  K0  NaN  NaN
1  A1  B1  K1  NaN  NaN
2  A2  B2  K2   C2   D2
3  A3  B3  K3   C3   D3 

 

 

 

 

  (2) Merge method : right (SQL join name : RIGHT OUTER JOIN)

 

 

In [9]: df_merge_how_right = pd.merge(df_left, df_right,

   ...: how='right',

   ...: on='KEY')


In [10]: df_merge_how_right

Out[10]:

     A    KEY   C   D
0   A2   B2  K2  C2  D2
1   A3   B3  K3  C3  D3
2  NaN  NaN  K4  C4  D4
3  NaN  NaN  K5  C5  D5

 

 

 

 

  (3) Merge method : inner (SQL join name : INNER JOIN)

 

 

In [11]: df_merge_how_inner = pd.merge(df_left, df_right,

    ...: how='inner', # default

    ...: on='KEY')

    ...:


In [12]: df_merge_how_inner

Out[12]:

    A   B KEY   C   D
0  A2  B2  K2  C2  D2
1  A3  B3  K3  C3  D3

 

 

 

 

  (4) Merge method : outer (SQL join name : FULL OUTER JOIN)

 

 

In [13]: df_merge_how_outer = pd.merge(df_left, df_right,

    ...: how='outer',

    ...: on='KEY')

    ...:


In [14]: df_merge_how_outer

Out[14]:

     A    B  KEY    C    D
0   A0   B0  K0  NaN  NaN
1   A1   B1  K1  NaN  NaN
2   A2   B2  K2   C2   D2
3   A3   B3  K3   C3   D3
4  NaN  NaN  K4   C4   D4
5  NaN  NaN  K5   C5   D5

 

 

 

[참고] Hive 조인 문 : INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL JOIN, CARTESIAN PRODUCT JOIN, MAP-SIDE JOIN, UNION ALL : http://rfriend.tistory.com/216

 

 

 

  (5) indicator = True : 병합된 이후의 DataFrame에 left_only, right_only, both 등의 

                              출처를 알 수 있는 부가정보 변수 추가

 

 

In [15]: pd.merge(df_left, df_right, how='outer', on='KEY',

    ...: indicator=True)

Out[15]:

     A    B KEY    C    D      _merge
0   A0   B0  K0  NaN  NaN   left_only
1   A1   B1  K1  NaN  NaN   left_only
2   A2   B2  K2   C2   D2        both
3   A3   B3  K3   C3   D3        both
4  NaN  NaN  K4   C4   D4  right_only
5  NaN  NaN  K5   C5   D5  right_only

 

 

 

위에서는 indicator=True로 했더니 '_merge'라는 새로운 변수가 생겼습니다.

 

이 방법 외에도, 아래처럼 indicator='변수 이름(예: indicator_info)'을 설정해주면, 새로운 변수 이름에 indicator 정보가 반환됩니다.

 

 

In [16]: pd.merge(df_left, df_right, how='outer', on='KEY',

    ...: indicator='indicator_info')

Out[16]:

     A    B KEY    C    D indicator_info
0   A0   B0  K0  NaN  NaN      left_only
1   A1   B1  K1  NaN  NaN      left_only
2   A2   B2  K2   C2   D2           both
3   A3   B3  K3   C3   D3           both
4  NaN  NaN  K4   C4   D4     right_only
5  NaN  NaN  K5   C5   D5     right_only

 

 

 

 

  (6) 변수 이름이 중복될 경우 접미사 붙이기 : suffixes = ('_x', '_y')

 

'B'와 'C' 의 변수 이름이 동일하게 있는 두 개의 DataFrame을 만든 후에, KEY를 기준으로 합치기(merge)를 해보겠습니다.  변수 이름이 중복되므로 Data Source를 구분할 수 있도록 suffixes = ('string', 'string') 을 사용해서 중복되는 변수의 뒷 부분에 접미사를 추가해보겠습니다.  default는 suffixes = ('_x', '_y') 입니다.

 

 

# making DataFrames with overlapping columns

In [17]: df_left_2 = DataFrame({'KEY': ['K0', 'K1', 'K2', 'K3'],

    ...: 'A': ['A0', 'A1', 'A2', 'A3'],

    ...: 'B': ['B0', 'B1', 'B2', 'B3'],

    ...: 'C': ['C0', 'C1', 'C2', 'C3']})


In [18]: df_right_2 = DataFrame({'KEY': ['K0', 'K1', 'K2', 'K3'],

    ...: 'B': ['B0_2', 'B1_2', 'B2_2', 'B3_2'],

    ...: 'C': ['C0_2', 'C1_2', 'C2_2', 'C3_2'],

    ...: 'D': ['D0_2', 'D1_2', 'D2_2', 'D3_3']})

    ...:


In [19]: df_left_2

Out[19]:

    A   B   C KEY
0  A0  B0  C0  K0
1  A1  B1  C1  K1
2  A2  B2  C2  K2
3  A3  B3  C3  K3


In [20]: df_right_2

Out[20]:

      B     C     D KEY
0  B0_2  C0_2  D0_2  K0
1  B1_2  C1_2  D1_2  K1
2  B2_2  C2_2  D2_2  K2
3  B3_2  C3_2  D3_3  K3

 


# adding string suffixes to apply to overlapping columns

In [21]: pd.merge(df_left_2, df_right_2, how='inner', on='KEY',

    ...: suffixes=('_left', '_right'))

    ...:

Out[21]:

    A B_left C_left KEY B_right C_right     D
0  A0     B0     C0  K0    B0_2    C0_2  D0_2
1  A1     B1     C1  K1    B1_2    C1_2  D1_2
2  A2     B2     C2  K2    B2_2    C2_2  D2_2
3  A3     B3     C3  K3    B3_2    C3_2  D3_3

 


# suffixes defaults to ('_x', '_y') 

In [22]: pd.merge(df_left_2, df_right_2, how='inner', on='KEY')

    ...:

Out[22]:

    A B_x C_x KEY   B_y   C_y     D
0  A0  B0  C0  K0  B0_2  C0_2  D0_2
1  A1  B1  C1  K1  B1_2  C1_2  D1_2
2  A2  B2  C2  K2  B2_2  C2_2  D2_2
3  A3  B3  C3  K3  B3_2  C3_2  D3_3

 

 

 

 

 

left_on, right_on, left_index, right_index 에 대해서는 다음번 포스팅에서 소개하도록 하겠습니다.

 

Posted by R Friend R_Friend

댓글을 달아 주세요

분석을 진행하다 보면 하나의 데이터 셋에서 변수를 생성, 제거, 변환하는 작업 못지않게 새로운 데이터 셋을 기존의 데이터 셋과 결합하는 작업 또한 빈번합니다.  이번 포스팅에서는 rbind(), cbind(), merge()함수를 활용해서 데이터 프레임 결합하는 방법에 대해서 알아보도록 하겠습니다.

 

예전에 포스팅 했던 R 행렬 함수(☞ 바로가기) 에서 rbind(), cbind()를 다루었던 적이 있는데요, 데이터 프레임도 행렬에서의 데이터 결합과 동일하며, 복습하는 차원에서 한번 더 짚어 보고, key값 기준으로 결합하는 merge()에 대해서 추가로 알아보도록 하겠습니다.

 

 

 R 데이터 프레임 결합 : rbind(), cbind(), merge()

 

[ rbind(), cbind(), merge() 함수 비교 ]

 

 

 

(1) 행 결합 (위 + 아래) : rbind(A, B)

 

먼저 실습에 사용할 데이터 프레임 두개(cust_mart_1, cust_mart_2)를 생성해 보겠습니다.

 

> ## 데이터 프레임 생성
> cust_id <- c("c01","c02","c03","c04")
> last_name <- c("Kim", "Lee", "Choi", "Park")
> cust_mart_1 <- data.frame(cust_id, last_name)
> 
> cust_mart_1
  cust_id last_name
1     c01       Kim
2     c02       Lee
3     c03      Choi
4     c04      Park
> 
> 
> cust_mart_2 <- data.frame(cust_id = c("c05", "c06", "c07"), 
+                           last_name = c("Bae", "Kim", "Lim"))
> 
> cust_mart_2
  cust_id last_name
1     c05       Bae
2     c06       Kim
3     c07       Lim

 

 

다음으로 두개의 데이터 프레임(cust_mart_1, cust_mart_2)을 세로 행 결합 (위 + 아래) 해보도록 하겠습니다.

 

> ## (1) 행 결합 (위 + 아래) rbind(A, B) > cust_mart_12 <- rbind(cust_mart_1, cust_mart_2) > > cust_mart_12 cust_id last_name 1 c01 Kim 2 c02 Lee 3 c03 Choi 4 c04 Park 5 c05 Bae 6 c06 Kim 7 c07 Lim

 

 

rbind()는 row bind 의 약자입니다. rbind()를 무작정 외우려고 하지 마시고, row bind의 약자라는걸 이해하시면 됩니다. 

위의 행 결합 rbind()를 하기 위해서는 결합하려는 두개의 데이터 셋의 열의 갯수와 속성, 이름이 같아야만 합니다. 

 

아래의 예시 처럼 만약 칼럼의 갯수가 서로 다르다면 (cust_mart_12는 열이 2개, cust_mart_3은 열이 3개) 열의 갯수가 맞지 않는다고 에러 메시지가 뜹니다.

 

> cust_mart_3 <- data.frame(cust_id = c("c08", "c09"), 
+                           last_name = c("Lee", "Park"), 
+                           gender = c("F", "M"))
> cust_mart_3
  cust_id last_name gender
1     c08       Lee      F
2     c09      Park      M
> rbind(cust_mart_12, cust_mart_3)
Error in rbind(deparse.level, ...) : 
  numbers of columns of arguments do not match

 

 

아래의 예처럼 칼럼의 이름(cust_mart_12 는 cust_id, last_name 인 반면, cust_mart_4는 cust_id, first_name)이 서로 다르다면 역시 에러가 납니다.

 

> cust_mart_4 <- data.frame(cust_id = c("c10", "c11"), 
+                           first_name = c("Kildong", "Yongpal"))
> cust_mart_4
  cust_id first_name
1     c10    Kildong
2     c11    Yongpal
> rbind(cust_mart_12, cust_mart_4)
Error in match.names(clabs, names(xi)) : 
  names do not match previous names 

 

 

(2) 열 결합 (왼쪽 + 오른쪽) : cbind(A, B)

 

> ## (2) 열 결합 cbind(A, B)
> 
> cust_mart_5 <- data.frame(age = c(20, 25, 19, 40, 32, 39, 28), 
+                           income = c(2500, 2700, 0, 7000, 3400, 3600, 2900))
> 
> cust_mart_12
  cust_id last_name
1     c01       Kim
2     c02       Lee
3     c03      Choi
4     c04      Park
5     c05       Bae
6     c06       Kim
7     c07       Lim
> cust_mart_5
  age income
1  20   2500
2  25   2700
3  19      0
4  40   7000
5  32   3400
6  39   3600
7  28   2900
> 
> cust_mart_125 <- cbind(cust_mart_12, cust_mart_5)
> cust_mart_125
  cust_id last_name age income
1     c01       Kim  20   2500
2     c02       Lee  25   2700
3     c03      Choi  19      0
4     c04      Park  40   7000
5     c05       Bae  32   3400
6     c06       Kim  39   3600
7     c07       Lim  28   2900

 

cbind()는 column bind의 약자입니다.   cbind()도 열 결합을 하려고 하면 서로 결합하려는 두 데이터셋의 관측치가 행이 서로 동일 대상이어야만 하고, 행의 갯수가 서로 같아야만 합니다

 

만약, cbind()를 하는데 있어 행의 갯수가 서로 다르다면 아래의 예처럼 에러 메시지가 뜹니다.

 

> cust_mart_6 <- data.frame(age = c(34, 50), + income = c(3600, 5100)) > cust_mart_6 age income 1 34 3600 2 50 5100 > cbind(cust_mart_125, cust_mart_6) Error in data.frame(..., check.names = FALSE) : arguments imply differing number of rows: 7, 2

 

 

 

(3) 동일 key 값 기준 결합 : merge(A, B, by='key)

 

두개의 데이터셋을 열 결합할 때 동일 key 값을 기준으로 결합을 해야 할 때가 있습니다.  cbind()의 경우 각 행의 관찰치가 서로 동일 대상일 때 그리고 갯수가 같을 때 가능하다고 했는데요, 만약 각 행의 관찰치가 서로 동일한 것도 있고 그렇지 않은 것도 섞여 있다면 그때는 cbind()를 사용하면 안됩니다.  이때는 동일 key 값을 기준으로 결합을 해주는 merge(A, B, by='key')를 사용해야만 합니다.

 

아래의 cbind()의 잘못된 예를 하나 보시겠습니다.

 

> cust_mart_12
  cust_id last_name
1     c01       Kim
2     c02       Lee
3     c03      Choi
4     c04      Park
5     c05       Bae
6     c06       Kim
7     c07       Lim
> 
> cust_mart_7 <- data.frame(cust_id = c("c03", "c04", "c05", "c06", "c07", "c08", "c09"), 
+                           buy_cnt = c(3, 1, 0, 7, 3, 4, 1))
> 
> cust_mart_7
  cust_id buy_cnt
1     c03       3
2     c04       1
3     c05       0
4     c06       7
5     c07       3
6     c08       4
7     c09       1
> cust_mart_127_cbind <- cbind(cust_mart_12, cust_mart_7)
> cust_mart_127_cbind
  cust_id last_name cust_id buy_cnt
1     c01       Kim     c03       3
2     c02       Lee     c04       1
3     c03      Choi     c05       0
4     c04      Park     c06       7
5     c05       Bae     c07       3
6     c06       Kim     c08       4
7     c07       Lim     c09       1
 
 

 

cust_mart_12 와 cust_mart_7 의 두 개의 데이터 프레임의 관측치가 서로 같은 것(cust_id 가 c03 ~ c07)도 있는 반면, 서로 다른 것(cust_id 가 c01~c02, c08~c09)도 있습니다.  이런 데이터 셋을 cbind()로 결합시켜버리면 엉뚱한 데이터 셋이 생성되어 버립니다. Oh no~!!!!!

 

이런 경우에는 동일한 key 값을 기준으로 결합을 시켜주는 merge(A, B, by='key')가 답입니다.

SQL에 익숙한 분들은 잘 아시겠지만, merge에는 기준을 어느쪽에 두고 어디까지 포함하느냐에 따라 Inner Join, Outer Join, Left Outer Join, Right Outer Join 등의 4가지 종류가 있습니다.  이를 도식화하면 아래와 같습니다.

 

[ merge() 함수의 join 종류 ]

 

 

위에 제시한 4가지 join 유형별로 merge() 함수 사용예를 들어보겠습니다.

 

(3-1) merge() : Inner Join 

 

> # (3-1) merge() : Inner Join > cust_mart_127_innerjoin <- merge(x = cust_mart_12, + y = cust_mart_7, + by = 'cust_id') > > cust_mart_127_innerjoin cust_id last_name buy_cnt 1 c03 Choi 3 2 c04 Park 1 3 c05 Bae 0 4 c06 Kim 7 5 c07 Lim 3

 

 

(3-2) merge() - Outer Join

 

> # (3-2) merge() : Outer Join > cust_mart_127_outerjoin <- merge(x = cust_mart_12, + y = cust_mart_7, + by = 'cust_id', + all = TRUE) > > cust_mart_127_outerjoin cust_id last_name buy_cnt 1 c01 Kim NA 2 c02 Lee NA 3 c03 Choi 3 4 c04 Park 1 5 c05 Bae 0 6 c06 Kim 7 7 c07 Lim 3 8 c08 <NA> 4 9 c09 <NA> 1 

 

 

(3-3) merge() : Left Outer Join

 

> # (3-3) merge() : Left Outer Join
> cust_mart_127_leftouter <- merge(x = cust_mart_12, 
+                                  y = cust_mart_7, 
+                                  by = 'cust_id', 
+                                  all.x = TRUE)
> 
> cust_mart_127_leftouter
  cust_id last_name buy_cnt
1     c01       Kim      NA
2     c02       Lee      NA
3     c03      Choi       3
4     c04      Park       1
5     c05       Bae       0
6     c06       Kim       7
7     c07       Lim       3 

 

 

(3-4) merge() : Right Outer Join

 

> # (3-4) merge : Right Outer Join
> cust_mart_127_rightouter <- merge(x = cust_mart_12, 
+                                  y = cust_mart_7, 
+                                  by = 'cust_id', 
+                                  all.y = TRUE)
> 
> cust_mart_127_rightouter
  cust_id last_name buy_cnt
1     c03      Choi       3
2     c04      Park       1
3     c05       Bae       0
4     c06       Kim       7
5     c07       Lim       3
6     c08      <NA>       4
7     c09      <NA>       1 

 

 

이상 merge() 함수의 4가지 유형의 join 에 대하여 알아보았습니다.  마지막으로, merge() 함수는 2개의 데이터 셋의 결합만 가능하며, 3개 이상의 데이터 셋에 대해서 key 값 기준 merge() 결합을 하려고 하면 에러가 나는 점 유의하시기 바랍니다.

 

> merge(cust_mart_12, cust_mart_5, cust_mart_7, by = 'cust_id')
Error in fix.by(by.x, x) : 
  'by' must specify one or more columns as numbers, names or logical

 

따라서 데이터 프레임 2개씩을 key 값 기준으로 순차적으로 merge() 해나가야 합니다.

 

이상으로 데이터 프레임의 결합에 대해서 마치도록 하겠습니다. 

많은 도움 되었기를 바랍니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

Posted by R Friend R_Friend

댓글을 달아 주세요

  1. AshtrayK 2016.09.02 14:14 신고  댓글주소  수정/삭제  댓글쓰기

    이번은 질문도 없네요 ㅎㅎㅎ
    감사합니다!

  2. 2016.09.22 16:08  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  3. 제발 2016.09.28 20:16  댓글주소  수정/삭제  댓글쓰기

    혹시 개인적으로 궁금한거 여쭤봐도될까요 ㅠㅠ

  4. 산낙지 2016.10.21 10:09  댓글주소  수정/삭제  댓글쓰기

    merge에 대해 이해가 너무 잘 되네요!
    좋은 설명 너무 감사합니다 ^^
    정말 구글에서는 영어로만 나와서 아무래도 찾기 막막했는데
    r friend님 블로그에 정리가 너무 잘 되어 있어서 항상 도움 받네요 ^^

  5. 바람 2017.05.31 15:23  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 merge와 join에 대하여 이해를 잘 했는데 혹시 데이터id 가 중복이 됐는데 다른 변수들 값이 다른 경우에 병합은 merge로 못하나요??

    • R Friend R_Friend 2017.05.31 15:27 신고  댓글주소  수정/삭제

      그런 경우라면 merge 시 뻥튀기가 될겁니다. id 외 추가로 key 값으로 쓸 수 있는게 있으면 paste로 id와 다른 변수를 합쳐서 새로운 key 변수 만든후에 merge하면 되구요.

  6. 2017.06.03 15:35  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  7. 너무 좋아요! 2018.08.27 18:03  댓글주소  수정/삭제  댓글쓰기

    잘 보고 있어요 너무 감사합니다. ㅎ

  8. 2018.12.02 16:10  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • R Friend R_Friend 2018.12.02 17:00 신고  댓글주소  수정/삭제

      분석 목적이 무엇인가, 분석기법이 무엇인가에 따라 자료 구조가 달라집니다. 분석 목적과 기법에 맞는 예제 자료 형태와 코드를 미리 살펴보시는게 좋겠습니다.

      melt, cast 함수를 사용하면 자료 구조를 원하는 형태로 바꾸실 수 있습니다.

  9. redsky 2019.10.31 16:53  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 항상 님 블로그에서 많은 도움을 받고 있습니다. 이번에 데이터를 정리하면서 엑셀 vlookup의 유사일치 기능 처럼 값이 완전히 일치하지 않고 유사한 경우에도 매칭을 시키고 싶은데 혹시 R의 merge 함수 에서도 이런게 가능한지 궁금합니다. 아니면 혹시 다른 함수로 구현이 가능하다면 좀 알려주시면 감사하겠습니다.

    • R Friend R_Friend 2019.10.31 17:47 신고  댓글주소  수정/삭제

      안녕하세요 redsky님.
      질믄하신 부분은 저도 해본적이 없어서 잘 모르겠네요. merge() 에서 바로 말고 다른 함수(regular expression??)에서 처리 후 merge 함수 사용해보는 방법도 있을거 같습니다.

    • R Friend R_Friend 2019.10.31 20:14 신고  댓글주소  수정/삭제

      간단한 예제 샘플 데이터와 로직, 그리고 아웃풋 이미지 남겨주시면 한번 살펴볼께요.

    • redsky 2019.11.04 11:29  댓글주소  수정/삭제

      아 감사합니다. 샘플 예제는 아래와 같습니다.
      1. 기준유량 : 10, 20, 30, 40, 50
      2. 기준유량 별 초과확률 : 90%, 80%, 70%, 60%, 50%
      3. 실측유량 : 19.8, 10.5, 50.5, 30.6, 39.1

      정해진 기준유량(1)과 각 기준유량별 초과확률(2) 데이터가 있고

      이때 실측유량(3) 값을 가장 근접한 기준유량(1) 값과 매칭하여

      해당 기준유량과 연결된 초과확률(2)을 구하려고 합니다.

      위 예시로 제가 원하는 결과 데이터는 80%, 90%, 50%, 70%, 60% 입니다.

      이게 엑셀에서는 vlookup으로 마지막 인수를 TRUE로 작성하면 비슷하게 일치하는

      데이터를 찾아줘서 쉽게 해결이 가능하긴 한데 워낙 데이터가 많아서

      R로 해볼려고 했더니 막상 이런 기능을 하는 함수를 모르겠네요;;

    • R Friend R_Friend 2019.11.04 11:54 신고  댓글주소  수정/삭제

      안녕하세요 redsky님,

      아래에 실제유량과 기준유량간의 거리(distance)를 구해서 최소거리 위치(index)의 초과확률을 가져오는(indexing) 코드를 짜보았습니다. 도움이 되었기를 바랍니다.

      # input data
      ref_flow <- c(10, 20, 30 40, 50)
      ref_excess_prob <- c(90, 80, 70, 60, 50)
      real_flow <- c(19.8, 10.5, 50.5, 30.6, 39.1)

      # blank vector to store the result
      real_excess_prob <- c()

      # for loop to get the most similar ref_flow and ref_excess_prob using distance

      for (i in 1:length(real_flow)){
      gap_abs <- abs(ref_flow - real_flow[i])
      min_idx <- which.min(gap_abs)
      real_excess_prob[i] <- ref_excess_prob[min_idx]
      }

      # print the result
      real_excess_prob
      [1] 80 90 50 70 60

    • redsky 2019.11.04 13:41  댓글주소  수정/삭제

      알려주신 방법으로 해봐야 겠네요.
      답변 정말 감사합니다~

    • R Friend R_Friend 2019.11.04 15:02 신고  댓글주소  수정/삭제

      도움이 되었기를 바래요. :-)