Skip to main content

R 기초, 조건에 맞는 데이터 선택하기

R좋은게 소문이 났는지? 주위에서 R을 배우는 교수님과 동료 선생님들이 늘어나는 것 같다. 나는 R을 엄청 잘 쓴다고 말은 못하지만, 어쩌다 보니 R에서 통계량 계산만 하고, Excel로 돌아가 다시 데이터를 정리해서 import하는 불필요한 일은 피할 정도가 되었다. 가끔은 사용자 함수를 만들어서 복잡한 text mining도 하고 반복작업을 줄이기도 한다. (매번 잘 되지는 않는다. 하지만 반복작업을 줄이는 코드를 만드는 것이 재미있다.)

논문 작성을 위한 데이터 정리를 노가다 또는 삽질이라고 부르는 친구들도 있지만 나는 그나마 R로 해결되는 것들이라면 코딩하는(?) 재미로 할 만 하다. 오늘부터는 이따금 R 사용법을 안내하는 글을 올려보려고 한다. 가르치는 것은 두 번 배우는 것이라 했으니 배운 것을 꼭꼭 씹어먹고 소화시키기 위함이다. (오늘만 해도 이걸 올리느라 R markdown을 배웠다. ㅎㅎ)

첫번째로, 가장 필요하고 중요하다고 생각되는 data frame의 subsetting 에 대해 써본다.



잘못된 정보가 있으면 댓글로 알려주시면 감사하겠습니다.

의학 논문 작성을 위한 R 기초

1. Data frame의 subsetting

1.1. Data frame과 vector

의학 연구자들이 기본적으로 사용하는 데이터는 열과 행으로 이루어진 데이터스프레드시트이다. 엑셀 등으로 작업이 된 경우도 있고 csv파일로 정리된 경우도 있는데 어쨌든 대부분은 csv파일로 변환해서 R에서 불러오게 된다.
example <- read.csv("c:/R/R_document/mtcars.csv", header = TRUE) #파일 경로는 이렇게
example <- read.csv("c:\\R\\R_document\\mtcars.csv", header = TRUE) #또는 이렇게도 가능하다.
#example <- read.csv("c:\\R\\R_document\\mtcars.csv", header = TRUE) 이렇게 쓰면 안 된다.

데이터를 R으로 불러오면 내부에서 data frame 형식으로 존재하게 된다.
class(example)
## [1] "data.frame"

하지만 data frame 형식의 데이터를 다루기 위해서는 다른 형식의 데이터셋(vector, matrix, list)에 대한 기본 지식을 갖추는 것이 좋다. 우선 vector만 이해해도 충분하다.

우선 불러온 데이터를 살펴보자. 데이터의 10행만 출력해보겠다.
head(example, 10) #10이라는 숫자를 입력하지  않으면 기본적으로 6줄을 보여준다.
##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4

여기서 첫번째 column만 따로 가져와보겠다. 여러가지 방법이 있다.
first_column_1 <- example$mpg #1
first_column_2 <- example["mpg"] #2
first_column_3 <- example[1] #3

세 가지 방법의 결과는 다르다. (1 ≠ 2 = 3) 결과물을 출력해보면
first_column_1
##  [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0
## [28] 30.4 15.8 19.7 15.0 21.4
class(first_column_1)
## [1] "numeric"
str(first_column_1) #구조를 보여준다.
##  num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...

첫 번째 방법은 example의 첫 column을 가져와서 (numeric) vector로 만든 것이다. Vector는 같은 형태(e.g. numeric, integer, charactor, factor, logical)의 데이터를 여러개 묶은 형태이다.
class(first_column_2)
## [1] "data.frame"
str(first_column_2)
## 'data.frame':    32 obs. of  1 variable:
##  $ mpg: num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
head(first_column_2, 3)
##    mpg
## 1 21.0
## 2 21.0
## 3 22.8

두 번째 방법은 data frame의 형태가 유지되어있다. Data frame이라 세로로 긴 여러행이라서 3줄만 출력하였다.

Vector의 특성에서 중요한 것은 logical vector로 부분집합을 가져올 수 있다는 것이다.
vector_1 <- c(15, 16, 17)
#c()는 벡터를 만드는 함수이다. 문자열 벡터는 따옴표 필요 c("a", "b")
vector_1[c(TRUE, FALSE, TRUE)] #1, 3번째 원소만 선택
## [1] 15 17
logical_1 <- c(TRUE, FALSE, TRUE) 
vector_1[logical_1] #이번엔 미리 만들어놓은 logical vector를 넣어서 선택해봤다.
## [1] 15 17

반대로 vector에 조건을 걸어 logical vector를 만들어낼 수 있는데 만들어낸 logical vector를 일종의 필터로 이용하여 다시 해당 조건의 원소를 추출할 수 있다.
logical_2 <- vector_1 > 15 #15보다 큰 원소는 TRUE로 그렇지 않으면 FALSE로 반환
logical_2
## [1] FALSE  TRUE  TRUE
vector_1[logical_2] #logical vector를 이용해서 해당 원소 추출
## [1] 16 17
vector_1[vector_1 > 15] #앞에서 한 것을 한 번에 쓰면
## [1] 16 17

1.2. Data frame의 subsetting - 기본

앞에서 불러온 data frame인 example의 특정 행과 열을 선택해보자.
example[1, 3] #1행 3열
## [1] 160
example[4, "disp"] #4행 disp열
## [1] 258
example[4, ] #4행
##    mpg cyl disp  hp drat    wt  qsec vs am gear carb
## 4 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
example[, "disp"] #disp열 = example$disp와 같다.
##  [1] 160.0 160.0 108.0 258.0 360.0 225.0 360.0 146.7 140.8 167.6 167.6 275.8 275.8 275.8 472.0 460.0 440.0  78.7  75.7  71.1 120.1 318.0 304.0
## [24] 350.0 400.0  79.0 120.3  95.1 351.0 145.0 301.0 121.0
example[5, c("mpg", "disp")] #5행, mpg와 disp열
##    mpg disp
## 5 18.7  360
example[5, c(1, 3)] #5행, 1과 3열
##    mpg disp
## 5 18.7  360
example[c(1:3), c(1:3)] #1-3행, 1-3열
##    mpg cyl disp
## 1 21.0   6  160
## 2 21.0   6  160
## 3 22.8   4  108
example[c(TRUE, FALSE), c(1:3)]
##     mpg cyl  disp
## 1  21.0   6 160.0
## 3  22.8   4 108.0
## 5  18.7   8 360.0
## 7  14.3   8 360.0
## 9  22.8   4 140.8
## 11 17.8   6 167.6
## 13 17.3   8 275.8
## 15 10.4   8 472.0
## 17 14.7   8 440.0
## 19 30.4   4  75.7
## 21 21.5   4 120.1
## 23 15.2   8 304.0
## 25 19.2   8 400.0
## 27 26.0   4 120.3
## 29 15.8   8 351.0
## 31 15.0   8 301.0
#c(TRUE, FALSE)는 전체 행 개수보다 적어서 이 두 값이 반복해서 대입되며 홀수행만 선택된다.
#행 개수에 맞는 logical vector를 넣어줄 수도 있다. (아래 응용편으로 이어지는 내용임.)

1.3. Data frame의 subsetting - 응용

앞에서 배운 것을 응용해보자. 특정 값을 기준으로 subsetting을 해보자. dataframe[logical vector, ]를 하게 되면 TRUE에 해당하는 행만 출력된다. logical vector를 만드는 법은 위에서 설명하였다.
selected <- example[example$mpg < 20, ] #mpg < 20인 행만 선택
head(selected)
##     mpg cyl  disp  hp drat   wt  qsec vs am gear carb
## 5  18.7   8 360.0 175 3.15 3.44 17.02  0  0    3    2
## 6  18.1   6 225.0 105 2.76 3.46 20.22  1  0    3    1
## 7  14.3   8 360.0 245 3.21 3.57 15.84  0  0    3    4
## 10 19.2   6 167.6 123 3.92 3.44 18.30  1  0    4    4
## 11 17.8   6 167.6 123 3.92 3.44 18.90  1  0    4    4
## 12 16.4   8 275.8 180 3.07 4.07 17.40  0  0    3    3

selected <- example[example$gear == 3, ] #gear = 3인 행만 선택
head(selected)
##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## 12 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## 13 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3

selected <- example[example$gear != 3, ] #gear = 3인 행만 제외
selected[order(selected$carb),] #carb값을 기준으로 오름차순으로 정렬
##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## 20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## 26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## 19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## 28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## 32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
## 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## 11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## 29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## 30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## 31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
selected[order(-selected$carb),] #carb값을 기준으로 내림차순 정렬
##     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## 30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## 11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## 29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## 19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## 28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## 32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
## 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## 18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## 20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## 26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1

이상의 기능들을 이용하면 기본적인 데이터 subsetting은 가능하다고 본다.

Comments

Popular posts from this blog

잘못 발음하기 쉬운 의학 용어 영어 단어 모음 (계속 업데이트)

의학 용어 영단어들은 대개 다 영어라서 한글로 바꾸기도 어렵고, 우리말로 바꿔놓은 텍스트를 읽노라면 원서를 읽는 것보다 머리가 더 지끈거릴 때도 있다. 하지만 원서는 그저 눈으로 읽을 뿐이다. 결국 발음은 제각각 다들 개성넘치게 하고 수업시간에도 웬만해서는 제대로 된 발음을 배울 수가 없다. 그렇게 의대 본과 4년, 인턴과 레지던트 5년 합쳐 9년 동안 굳어진 잘못된 발음을 이후에도 계속 쓰는게 일반적이다. 이왕 하는 영어 공부 내 전공에도 접목시켜보자. 매번 마음속으로 갸우뚱하며 자신없이 발음했던 의학 용어들을 머릿속에 떠오르는 대로 검색해 목록을 만들었다. 앞으로 발음이 헷갈리는 다른 의학 용어가 생길 때마다 바로 사전을 찾아보든지 유튜브를 찾아보고 정리해놓을 예정이다. 작심삼일이 되지 않기를 바랄 뿐이다. (마지막 업데이트 2020. 5. 27.) 단어 / Pronunciation symbols (Merriam-Webster dictionary) Anatomy-related pulmonary /  ˈpu̇l-mə-ˌner-ē / ㅓ와ㅜ의 중간느낌? 퍼ㅜㄹ머네리 *Cambridge [ˈpʊl.mə.ner.i], Oxford [|pʌlməneri], Collins  [pʌlməneri] mediastinum / mē-dē-ə-ˈstī-nəm / 메디아스티넘 아니고 미디어스타이넘 endocrine / ˈen-də-krən  , -ˌkrīn, -ˌkrēn / 엔도크라인 아니고 엔도크런, 엔도크린 aorta /  ā-ˈȯr-tə / 아올타 아니고 에이올더 atrium / ˈā-trē-əm / 아트리움 아니고 에이트리엄 myocardium / mī-ə-ˈkär-dē-əm / 마이오카ㄹ디엄 branchial / ˈbraŋ-kē-əl / 브랜키-얼 bronchial / ˈbräŋ-kē-əl / 브란키-얼 bronchiole / ˈbräŋ-kē-ˌōl / 브란키-오울 azygos / (ˌ)ā...

Drinking culture in Korea: Honsul (drinking alone) / 한국의 음주 문화: 혼술

Honsul (혼술, drinking alone) is a combination of two words, honja (혼자, alone) and sul-masigi (술 마시기, drinking). It has become a trendy and widely used word to describe how people have been drifting away from drinking with company since the 2010s. This trend is generally thought of as driven by the growing number of people in their 20s and 30s who are living alone. '혼술'은 '혼자'와 '술 마시기'의 합성어입니다. 이 단어는 사람들이 무리지어 음주를 하는 것을 기피하는 현상을 나타내는 단어로 2010년대 이후 유행하여 널리 쓰이게 되었습니다. 혼자 사는 20대, 30대 인구가 늘어나면서 이들이 이러한 문화를 주도하는 것으로 알려져 있습니다. Honsul at home (only two days ago) Honsul as a counter-reaction to hoe-sik 혼술, 회식 문화에 대한 반작용 Drinking alone never used to be common in Korea. Many people who were born in the 1960s and 70s are heavily group oriented. They highly value group activities and like to do everything "together." Members of their groups aren't allowed to say "no" to group activities. As they are now in key positions of companies, the...

잘못 알고 틀리게 발음하던 영어 단어 정리 (계속 업데이트)

나는 원어민처럼 부드럽게 굴러가는 발음은 바라지도 않는다. 그런데 가끔 눈으로 보고 읽는 영단어 조차도 발음하는 법을 모르거나, 자신있게 틀린 발음으로 말한뒤 뒤늦게 그것이 백번 양보해도 근본없는 엉터리 영어 발음이었다는걸 알게 되면 굉장히 부끄럽고 난감하다. 안다고 생각했던 단어조차 실제 발음이 내 생각과 전혀 달라서 깜짝 놀라기도 한다. 발음을 들어보지 않고 눈으로만 단어를 외우면 이렇게 된다. (아마 많은 한국인들이 나와 같은 실수를 매일 반복하고 있을 것이다.) 이제는 영단어를 찾아볼 때 발음을 꼭 들어보고 영어 발음 기호에도 관심을 기울이고 정리해두려고 한다. 이미 American English 발음에 익숙해져 있으므로 대중적인 Merriam-Webster 영영사전으로 찾아보기로 했다. 그런데Merriam-Webster에서는 내가 알던 발음 기호(IPA, International Phonetic Alphabet)가 아니라 다른 기호를 쓰고 있기에 우선 기호에 익숙해질 필요가 있어 보인다. ( Guide to Pronunciation  참조) 영영사전 속 오디오와 발음기호를 이용하여 공부해보고 그래도 애매한 것은 Youglish.com에서 실제 발음을 검색하며 공부하려고 한다. 아래 리스트는 내가 정리한 단어 목록인데 나 외에 여러 한국인들이 잘못 알고 발음을 틀리기 쉬운 단어들이 꽤 포함되어 있을 것이라 생각해서 공유해본다. (2020. 4. 21. 업데이트) 단어 / Pronunciation symbols (Merriam-Webster dictionary) 비교하며 볼 단어 cafe ( café ) / ka-ˈfā / 카페 아니고 캐페이 latte / ˈlä-(ˌ)tā / 라테이 frappe / fra-ˈpā / 프래페이 position / pə-ˈzi-shən / 포지션 아니고 퍼지션 solution / sə-ˈlü-shən / 솔루션 아니고 설루션 report / ri-ˈpȯrt...