data.table 패키지 기초

R data.table Lecture

데이터를 빠르게 가공할 수 있는 data.table에 대하여 패키지 설치부터, 기본 구조 및 데이터를 가공하여 재구조화 하는 방법에 대해서 소개합니다.

KO JUN HYUK https://github.com/junhyuk0330
2022-07-13

1. data. table

1-1. data.table 특징

data.table은 빠른 속도와 메모리 효율성에 가장 적합한 패키지입니다.

대용량의 데이터를 분산처리 시스템 없이 처리할 수 있습니다.

데이터 프레임(data.frame)을 대신하여 더 빠르고 편리하게 사용할 수 있는 데이터 타입입니다.

1-2. 생성하기

본격적으로 data.table에 대해서 알아보기 전에, Setup 과정에 대해서 먼저 소개하려고 합니다. data.table은 R에서 기본적으로 제공되는 데이터 구조가 아니기 때문에, package 설치가 필요합니다.

## Setup
# install.packages("data.table")
# install.packages("curl")
library(data.table)
library(curl)

위의 과정을 통해 pacakge 설치 및 불러오기를 실행합니다.

data.table을 생성하는 데는 두 가지 방법이 있습니다.

첫번째는, data.table() 함수를 통해 직접 생성하는 방식입니다. 다음의 예시로 살펴보겠습니다.

EX=data.table(
  ID=c("A","B","C","D","E"),
  MATH=c(100,96,94,88,92),
  ENGLISH=c(96,86,97,92,93),
  HISTORY=c(85,92,87,92,94))
ID MATH ENGLISH HISTORY
A 100 96 85
B 96 86 92
C 94 97 87
D 88 92 92
E 92 93 94

ID, MATH, ENGLISH, HISTORY를 변수로 한, data.table이 형성된 것을 확인할 수 있습니다.

두번째는, 기존의 데이터를 불러오는 방법이 있습니다.

fread 함수는 대용량 파일을 빠르게 가져올 수 있는 함수입니다. 파일을 읽어와서 data.table 형식의 자료로 만들 때, 로컬 file path를 입력하거나, http://로 시작하는 URL을 입력하는 방법을 사용할 수 있습니다.

library(data.table) ; library(magrittr)
df <- read.csv("https://raw.githubusercontent.com/jinseob2kim/lecture-snuhlab/master/data/example_g1e.csv")
dt <- fread("https://raw.githubusercontent.com/jinseob2kim/lecture-snuhlab/master/data/example_g1e.csv")

09-15년 공단 건강검진 데이터에서 실습용으로 32명을 뽑은 자료를 이용하여,

df에는 data.frame 형식으로 데이터를 불러왔고, dt에는 fread 함수를 이용하여 data.table의 형식으로 데이터를 불러온 것을 확인할 수 있습니다.

fread 함수로 파일을 불러오면 그 class는 data.frame에 data.table이 추가되며, 문법이 원래의 data.frame과 달라지는 점을 유의해야 합니다.

class 함수를 통해 df와 dt의 속성을 확인해보겠습니다.

print(class(df)) ; print(class(dt))
[1] "data.frame"
[1] "data.table" "data.frame"

dt의 class에 data.table이 추가된 것을 확인할 수 있습니다.

지금까지 data.table을 생성하는 두 가지 방법에 대해서 알아보았습니다.

다음으로 data.table이 data.frame과 다른 점은, 행(Row)의 이름을 받지 않는 것을 기본값으로 한다는 것입니다.

예시로 알아보도록 하겠습니다.

R에 기본적으로 저장되어 있는 mtcars 데이터를 이용하도록 하겠습니다.

# mtcars
EX1<-as.data.frame(mtcars)
EX2<-as.data.table(mtcars)

실행하였을 때, EX1과 EX2의 행의 이름에서 차이점이 있음을 확인할 수 있습니다.

만약, data.table에서도 행의 이름을 남겨 놓고 싶을 때는 다음과 같이 실행하면 됩니다.

EX3<-as.data.table(mtcars,keep.rownames=T)

data 값 뒤에 keep.rownames=T로 설정하였을 때,

각 행의 이름이 rn 컬럼에 남아 있는 것을 확인할 수 있습니다.

1-3. 기본문법

data.table의 기본 문법은 DT[i, j, by] 형태입니다.

1-4. 특수기호

data.table에서만 확인할 수 있는 특수기호들이 있습니다.

각 특수기호의 자세한 기능과 사용법은 이하에서 설명하기로 하고, 여기에서는 간단히 개념정도만 다뤄보려고 합니다.

이상에서 data.table을 이용하면서 가장 많이 쓰이는 특수기호들에 대해서 알아보았습니다. 각각의 특수기호들이 어떻게 실제로 쓰이는지에 대해서는 이하에서 등장할 때마다 자세하게 설명하도록 하겠습니다.

2. data.table에 접근하기

이하에서는 위에서 불러온 dt(=09-15년 공단 건강검진 데이터)와 EX3(=mtcars) 데이터를 이용해서 실습하려고 합니다.

2-1. 행(Row)에 접근하기

data.table에서 행(Row)에 접근하는 방법은 DT[i, j, by]에서 i 자리에 값을 넣는 것입니다. 즉, DT[c(row1, row2, …)]의 방식입니다.

mtcars 데이터로 예시를 들어보겠습니다.

여러 개의 자동차 종류 중, Datsun 710과 Hornet Sprotabout에 대해서만 알아보고 싶을 때는 다음과 같이 작성하면 됩니다.

EX3[c(3,5)]
rn mpg cyl disp hp drat wt qsec vs am gear carb
Datsun 710 22.8 4 108 93 3.85 2.32 18.61 1 1 4 1
Hornet Sportabout 18.7 8 360 175 3.15 3.44 17.02 0 0 3 2

만약 Mazda RX4 부터 Hornet Sportabout까지 알아보고 싶다면, 범위로 지정할 수도 있습니다.

EX3[1:5]
rn mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2

여기서 중요한 것은 DT[i, j, by]라는 기본적인 형식에서 i의 자리에 지금 내용을 채워 넣는 것인데, i 자리에 내용을 작성한 후 꼭 콤마(,)를 찍지 않아도 된다는 것입니다. 꼭 콤마(,)를 찍지 않아도 뒤에 특정한 열 을 선택하지 않으면 모든 열에 대해서 알아서 필터링을 하기 때문입니다.

다음으로는 특정 조건을 만족하는 행(row)을 선택하는 방법에 대해서 알아보려고 합니다.

DT[조건]의 형식을 이용하면 됩니다.

mtcars 데이터에서 cyl>=6이면서, carb==4인 조건을 만족하는 데이터를 찾고 싶은 경우, 다음과 같이 작성하면 됩니다.

EX3[cyl>=6 & carb==4]

KEY를 미리 설정해놓으면 더 빠르게 검색할 수 있는데, 이 내용에 대해서는 뒤에서 자세하게 다루도록 하겠습니다.

다음으로는 특정 행(row)을 제외하는 방법에 대해서 알아보려고 합니다. 제외하려는 행 혹은 행의 범위 앞에 -! 를 붙여주면 됩니다.

EX3[!1:5]
EX3[-2]

위와 같이 실행했을 때, 제외하려는 데이터가 사라진 것을 확인할 수 있습니다.

2-2. 열(Column)에 접근하기

행(Row)을 선택할 때와 유사합니다. 기본적인 형식은 DT[i, j, by]의 j 자리에 넣는 것입니다.

mtcars 데이터에서 ‘cyl’ 열(Column)을 가져오고 싶을 때는 다음과 같이 가져올 수 있습니다.

EX3[,3] ; EX3[,.(cyl)] ; EX3[,"cyl"]
cyl
6
6
4
6
8
6

열(column)의 숫자로 불러와도 되고, 변수의 이름으로 불러오는 것도 가능합니다. 그런데, 여기서 중요하게 봐야할 점은 변수의 이름으로 가져올 때 앞에 .()의 형식을 이용했다는 점입니다.

.()list()와 동일한 기능을 하는데, 조금 더 간편하게 쓸 수 있는 형식이라 생각하면 됩니다.

data.table에서는 변수의 이름만 넣었을 경우, 벡터의 형식으로 값을 불러옵니다. 그렇기 때문에 data.table의 형식을 유지하면서 데이터를 불러오려면 .() 혹은 list() 형식을 이용해야 합니다. 혹은 변수를 따옴표를 이용하여 작성하는 것도 동일한 결과를 가져옵니다.

열(column)을 선택할 때, DT[,.(new_col_name=col)] 형식을 사용하여 새로운 열 이름을 지정해서 출력할 수도 있습니다.

EX3[,.(MPG=mpg, CYL=cyl)]

위와 같이 mpg와 cyl에 대해서 변수 이름을 대문자로 바꿔준 것을 확인할 수 있습니다.

다음으로는 변수로 열을 선택하는 방법에 대해서 알아보려고 합니다.

예시를 위해 mpg, cyl, disp 세 변수를 묶는 VARS라는 새로운 변수를 임의로 설정하겠습니다.

VARS<-c("mpg","cyl","disp")
EX3[,..VARS]

VARS 라는 변수를 넣었을 때, 위에서 설정한 것처럼 mpg, cyl, disp에 대한 값들만 추출한 것을 확인할 수 있습니다. 여기서 중요한 것은, 변수 앞에 .. 을 넣어줬다는 것입니다.

data.table의 약속이라고 보면 되는데, 같은 결과를 도출하는 다른 형식들에 대해서 소개하려고 합니다.

우선은, with = F가 있습니다.

EX3[,VARS,with=F]

VARS 앞에 ..을 붙이지 않아도, with=F를 추가한다면 같은 결과를 도출하는 것을 확인할 수 있습니다.

다음으로는 앞서 배운 .SD.SDcols를 이용하는 방법에 대해 알아보겠습니다.

EX3[,.SD,.SDcols=VARS]

.SD를 통해 전체 변수를 대상으로 하되, .SDcols로 특정 변수만을 설정하는 메커니즘입니다.

또한 특정조건을 만족하는 값들에 대해 VARS의 변수 값을 알고 싶으면 다음과 같이 실행하면 됩니다.

EX3[hp>=130 & gear>=4, ..VARS]

hp가 130을 넘고, gear가 4를 넘는 값들 중 VARS(mpg,cyl,disp) 변수에서 해당하는 값들을 보여주는 것을 확인할 수 있습니다.

다음으로는 열을 제거하는 방법에 대해서 알아보려고 합니다. 행(row)을 제거할 때와 유사하게 - , ! 을 통해서 실행하면 됩니다. 그리고 같은 결과를 도출하는 다른 형식들에 대해서도 소개하려고 합니다.

EX3[,-..VARS] ; EX3[,!..VARS] ; EX3[,.SD,.SDcols=-VARS]

마지막으로 열(column)의 값에 대해서 함수들을 이용해 값들을 가공하는 방법입니다.

mpg와 hp의 평균에 대해서 구해보겠습니다.

EX3[,.(mean(mpg), mean(hp))]

값을 실행할 경우, V1, V2라는 변수 아래에 값이 도출되는 것을 확인할 수 있습니다.

위에서 배웠던, 변수에 새로운 이름을 부여하는 방식을 이용해보겠습니다.

EX3[,.(MEAN_mpg=mean(mpg), MEAN_hp=mean(hp))]

위와 동일한 값에 변수의 이름이 생긴 것을 확인할 수 있습니다.

.SD, .SDcols를 이용해서도 도출할 수 있습니다.

EX3[,lapply(.SD,mean), .SDcols=(c("mpg", "hp"))]
mpg hp
20.09062 146.6875

또한 행(row)의 자리에 특정 조건을 입력하여, 특정 조건을 만족하는 변수들에 대해서만 특정 함수를 적용할 수도 있습니다.

EX3[gear==4, lapply(.SD,mean), .SDcols=c("mpg","hp")]
mpg hp
24.53333 89.5

2-3. by에 접근하기

by는 집단을 나눕니다. 정확히는 옵션을 이용하여 그룹별로 함수를 적용할 수 있습니다.

by = (그룹1, 그룹2, …)의 형식으로 두 개 이상의 그룹별로 함수를 적용할 수도 있는데, 이 때 괄호 앞에 있는 점(.)은 list를 의미하므로 꼭 포함시켜야 합니다. (ex. by=.(EXMD_BZ_YYYY, Q_SMK_YN) 와 같이 두 개 이상의 그룹으로 묶을 때는 .()의 형식을 이용해야 합니다.)

어떻게 쓰이는지 바로 알아보도록 하겠습니다.

여기에서는 dt(=09-15 공단 건강검진 데이터)를 이용해서 실습해보려고 합니다. EXMD_BZ_YYYY을 기준으로 집단을 분리한 후, 각 집단의 HGHT와 WGHT, BMI 평균을 구하는 방법은 다음과 같습니다.

dt[,.(HGHT=mean(HGHT), WGHT=mean(WGHT), BMI=mean(BMI)), by= EXMD_BZ_YYYY]

EXMD_BZ_YYYY에 따라 각 연도를 기준으로, HGHT, WGHT, BMI가 정렬이 되었고, 그 값들의 평균을 그룹별로 구하여 나타낸 데이터 값입니다.

만약 특정한 변수가 아닌, 모든 변수에 대해서 평균을 구하고 싶다면 .SD를 이용하면 됩니다.

dt[,lapply(.SD,mean), by=EXMD_BZ_YYYY]

위의 값은 평균을 낼 수 없는 변수들에 대해서도 일괄적으로 평균을 돌렸기 때문에 NA 값이 도출되었습니다. 값에 집중하기보다, 전체에 대한 함수를 적용하는 방식에 대해서 알아두면 좋을 것 같습니다. 만일 전체가 아닌 특정 변수에만 함수를 적용하고 싶다면 .SDcols 을 이용하면 됩니다.

다음으로는 두 개 이상의 그룹 변수를 지정해 행(row)의 개수를 구해보겠습니다.

키가 175cm 이상인 사람들에 대해서, 연도(EXMD_BZ_YYYY)와 흡연 여부(Q_SMK_YN)로 구분해보려고 합니다.

dt[HGHT>=175, .N, by=.(EXMD_BZ_YYYY, Q_SMK_YN)]

위에서 잠깐 언급한 .N 을 이용하여 특정조건에 부합하며 각 변수값에 해당되는 행(row)의 수를 구해보았습니다. 그러나, 여기에서 도출된 결과값의 문제는 Q_SMK_YN의 값이 섞여 있다는 것입니다.

조금 더 정렬된 결과값으로 나타내고 싶을 때는, by 대신에 keyby를 이용하면 됩니다. keyby는 기존의 by에 오름차순/내림차순 기능이 포함되었다고 생각하면 됩니다. 만약 by를 이용하면서 정렬을 시키고 싶다면 마지막에 [order(정렬기준)]를 붙이면 됩니다.

dt[HGHT>=175, .N, keyby=.(EXMD_BZ_YYYY, Q_SMK_YN)]
dt[HGHT>=175, .N, by=.(EXMD_BZ_YYYY, Q_SMK_YN)][order(EXMD_BZ_YYYY)]

연도를 기준으로 정렬을 하고 싶은 경우, 위와 같이 뒤에 [order(EXMD_BZ_YYYY)]를 붙여주면, 위의 값과 다르게 정렬된 것을 확인할 수 있습니다.

다음으로, 특정 조건(HGHT>=175)를 만족시키면서, 하나의 기준을 더 추가하여 분류하고 싶을 때는 다음과 같은 방식을 이용하면 됩니다.

dt[HGHT>=175, .N, keyby=.(Y2015 = ifelse(EXMD_BZ_YYYY>=2015, ">=2015", "<2015"))]
Y2015 N
<2015 206
>=2015 36

HGHT가 175 이상인 사람들을 우선으로 뽑아놓고, 거기에서 Y=2015를 기준으로 행(row)의 갯수를 확인하였습니다.

3. 다른 기능들

3-1. setkey()

키를 설정합니다. 키를 활용하는 이유는 자료를 찾을 때, 그 탐색 및 처리 시간을 단축시키기 위함입니다.

setkey(DT,col)로 키를 설정하며 키가 문자열 벡터일 경우 setkeyv을 활용합니다.

만일 설정된 키를 제거할 경우, setkey(DT, NULL)를 활용합니다.

dt 데이터를 이용하여, key를 설정하고 활용해보겠습니다.

setkey(dt, EXMD_BZ_YYYY)
key(dt)
[1] "EXMD_BZ_YYYY"

dt의 키로 EXMD_BZ_YYYY가 설정된 것을 확인할 수 있습니다. 다른 변수들도 setkey 함수에 추가로 입력하면, 그 변수들이 key로 저장된 것을 확인할 수 있습니다.

다음으로는 키를 활용한 행(row) 선택에 대해서 알아보려고 합니다. dt[.(a)], dt[J(a)], dt[list(a)], dt[col==a] 중에서 아무거나 사용하여 행을 선택할 수 있습니다. 위에서 EXMD_BZ_YYYY를 key로 설정하였기 때문에, dt[J(a)]에서 a의 자리에 EXMD_BZ_YYYY에 포함되어 있는 값을 넣으면 그 값을 기준으로 데이터를 정리합니다.

예시로,

dt[J(2013)]

이 값의 경우, EXMD_BZ_YYYY가 2013인 값에 대하여 정리한 것을 확인할 수 있습니다.

만약, key를 두 개 이상 설정해놓은 경우, a의 자리에 다른 조건을 연결하면 그 조건도 포함하고 있는 값이 도출됩니다.

setkey(dt, EXMD_BZ_YYYY, Q_HBV_AG)
key(dt)
[1] "EXMD_BZ_YYYY" "Q_HBV_AG"    
dt[J(2013,2)]

위의 과정은 key에 Q_HBV_AG를 추가한 뒤, 2013년도에 Q_HBV_AG가 2인 값들에 대해서 정리한 것입니다.

3-2. Merge : data.table 병합

다음으로는 두 개의 data.table에 대해서 공통된 column을 기준으로,

하나의 data.table로 만드는 방법에 대해서 소개하려고 합니다.

dt 파일의 설문조사에 관한 데이터(Q_)들을 하나의 변수 colvars로 편의를 위해 설정하였습니다.

colvars<-grep("Q_", names(dt), value=T)

다음으로는 dt 데이터를 임의로 분리하여 dt1, dt2를 설정하겠습니다.

dt1<-dt[1:10, .SD, .SDcols=c("EXMD_BZ_YYYY", "RN_INDI", "HME_YYYYMM", colvars)]
dt2<-dt[6:15, -..colvars]

본격적인 분석을 하기에 앞서, dt1 과 dt2에 대해서 간단히 살펴보겠습니다.

행(row)을 기준으로는 6:10행까지가 겹치고,

열(column)을 기준으로는 “EXMD_BZ_YYYY”, “RN_INDI”, “HME_YYYYMM” 이 공통입니다.

dt1, dt2 데이터를 이용해 merge 함수에 대해서 알아보도록 하겠습니다.

merge 에는 inner_join, full_join, left_join, right_join, anti_join 등이 있습니다.

하나하나씩 예시와 함께 알아보도록 하겠습니다.

처음으로 알아볼 것은 inner_join 입니다. 집합의 교집합 개념과 유사하지만, 약간의 차이점은 존재합니다.

inner_join(dt1,dt2)
merge(dt1, dt2, by=c("EXMD_BZ_YYYY", "RN_INDI", "HME_YYYYMM"), all=F)

우선 inner_join을 실행함에 있어 단순하게 inner_join 함수를 이용해도 되지만, merge 함수에서 공통 변수인 “EXMD_BZ_YYYY”, “RN_INDI”, “HME_YYYYMM”을 직접 merge의 매개체로 설정할 수도 있습니다. 그리고 inner_join의 경우, merge 함수의 뒤에 all=F가 들어간다는 것을 유의하시면 될 것 같습니다. (뒤에 full_join과 비교)

inner_join을 실행하였습니다. dt1과 dt2의 공통 행(row)에 속하는 6:10행까지를 기준으로 정렬하되, 각 값들이 dt1, dt2에서 가지고 있던 변수 값들도 그대로 가져온 것을 확인할 수 있습니다.

결과값의 RN_INDI가 714509인 값을 살펴보겠습니다.

이 변수값은 원래 dt1에서는 HGHT와 WGHT 등의 값을 가지고 있지 않았습니다. 그러나, inner_join을 하면서 dt2의 값을 그대로 받아와, HGHT, WGHT 등의 값을 부여받은 것을 확인할 수 있습니다.

다음으로는 full_join 입니다. 집합의 합집합 개념과 유사합니다.

full_join(dt1, dt2)
merge(dt1, dt2, by=c("EXMD_BZ_YYYY", "RN_INDI", "HME_YYYYMM"), all=T)

full_join을 실행하였습니다. dt1과 dt2의 모든 행이 나열된 것을 확인할 수 있습니다. (공통된 행(row)은 한번만 표시되었습니다. 또한 inner_join과 다르게 all=T 임을 확인할 수 있습니다.)

여기서 유심히 봐야할 것은 1:5, 11:15행입니다.

1:5행의 경우에는 dt에는 속해 있지만, dt2에는 속해있지 않습니다. 그렇기 때문에 1:5행은 HGHT, WGHT 등 dt2에만 있는 값들에 대해서는 받을 값이 존재하지 않아, NA로 표시된 것을 확인할 수 있습니다.

반면, 11:15행의 경우에는 dt2에는 속해 있지만, dt1에는 속해있지 않습니다. 그렇기 때문에 Q_로 시작하는 변수값에 대해서 받을 수가 없어서 NA로 나온 것을 확인할 수 있습니다.

다음으로는 left_join과 right_join 입니다.

left_join(dt1,dt2)
merge(dt1, dt2, by=c("EXMD_BZ_YYYY", "RN_INDI", "HME_YYYYMM"), all.x=T)
dt2[dt1, on = c("EXMD_BZ_YYYY", "RN_INDI", "HME_YYYYMM")]

left_join을 실행하였습니다. 변수의 값이 dt1의 row를 기준으로 설정된 것을 확인할 수 있습니다. 그러나, dt2의 column이 추가되어, HGHT, WGHT 등 기존의 dt1에 없던 변수들이 생긴 것을 확인할 수 있습니다. inner_join과 유사하게, dt2에 있는 변수들에 대해서는 left_join을 했을 때도, 원래 dt1에는 없었던 HGHT, WGHT 등의 값이 새로 생긴 것을 확인할 수 있습니다.

right_join으로도 직접 실습하여 차이를 확인하시기 바랍니다.

하나의 차이가 있다면, left_join을 했을 때는 all.x = T 였지만, right_join의 경우에는 all.y =T 를 사용합니다.

right_join(dt1, dt2)
merge(dt1, dt2, by=c("EXMD_BZ_YYYY", "RN_INDI", "HME_YYYYMM"), all.y=T)
dt1[dt2, on = c("EXMD_BZ_YYYY", "RN_INDI", "HME_YYYYMM")]

마지막으로 anti_join이 있습니다. 예시부터 보이고 설명하도록 하겠습니다.

anti_join(dt1,dt2)
dt1[!dt2, on = c("EXMD_BZ_YYYY", "RN_INDI", "HME_YYYYMM")]

직관적으로 확인할 수 있듯, dt2와 겹치지 않는 dt1의 값들에 대해서만 나타낸 것을 확인할 수 있습니다. 또한 다른 join들이 dt2의 column(variable)을 가져왔던 것과 다르게, anti_join은 오직 dt1의 변수들로만 구성된 것을 확인할 수 있습니다.

만약에 anti_join(dt2,dt1) (또는, dt2[!dt1, on = c(“EXMD_BZ_YYYY”, “RN_INDI”, “HME_YYYYMM”))은 이라고 작성한다면 위와 반대로 dt2를 기준으로 데이터의 값이 도출됩니다.

3-3. 수정 연산자 :=

data.table에서 열 j를 추가하거나 갱신 또는 삭제할 때 특수 기호 := 연산자를 사용합니다.

수정 또는 생성하는 column이 두 개 이상이라면, DT[,c(“cola”, “colb”) := list(valA,valB)] 또는, DT[, “:=”(cola, colb)]의 형식을 사용합니다.

즉, := 는 새로운 data.table을 생성하지 않고 기존의 데이터 테이블에 덮어씌우거나(수정), 새로운 컬럼을 추가합니다.

다음 예시로 알아보겠습니다.

BMI2 라는 새로운 변수를 data.table에 추가하려고 합니다.

(BMI2 = WGHT/(HGHT/100)^2 를 하고, 소수점 첫째자리까지 반영)

dt[, BMI2 := round(WGHT/(HGHT/100)^2, 1)]

열(column)의 맨 마지막에 BMI2가 새롭게 생긴 것을 확인할 수 있습니다.

다음으로는 특정 조건을 충족하는 값들에 대해서 새로운 변수를 만들어 확인하는 것에 대해서 알아보려고 합니다.

두 가지 조건을 설정하겠습니다. 하나는, BP_SYS가 140이 넘는지 그리고 BMI가 25가 넘는지에 대해서, factor로 바꾸어 0과 1로 나타내는 column에 대해서 추가하려고 합니다.

dt[, ':=' (BP_SYS140 = factor(as. integer(BP_SYS>=140)), BMI25 = factor(as.integer(BMI>=25)))]