data.table

data.table은 다른 package보다 빠르게 data를 다룰수있습니다. 예를 들어 data를 합치거나 data 안에서 새로운 변수를 만들때 원하는 특정 변수만을 선택하여 새로운 변수를 만들때 빠르고 편리하게 쓸수있습니다.

# 속도 차이
N <- 1e+06
d1 <- data.frame(x = sample(N, N), y1 = rnorm(N))
d2 <- data.frame(x = sample(N, N), y2 = rnorm(N))
system.time(d <- merge(d1, d2))
##    user  system elapsed 
##    6.62    0.29    6.94

# sqldf package를 사용하여 자료를 합치기
library(sqldf)
sqldf()
## <SQLiteConnection: DBI CON (4392, 0)>
sqldf("create index ix1 on d1(x)")
## NULL
sqldf("create index ix2 on d2(x)")
## NULL
system.time(d <- sqldf("select * from d1 inner join d2 on d1.x=d2.x"))
##    user  system elapsed 
##    4.86    0.06    4.95


# plyr package를 이용하여 자료를 합치기
library(plyr)
system.time(d <- join(d1, d2))
##    user  system elapsed 
##    9.61    0.23    9.89


# data.table을 이용하여 자료를 합칠때 다른 package 보다 훨씬 빠르게
# 처리합니다.
library(data.table)
dt1 <- data.table(d1, key = "x")
dt2 <- data.table(d2, key = "x")
system.time(d <- data.frame(dt1[, list(x, y1, y2 = dt2$y2)]))
##    user  system elapsed 
##    0.14    0.03    0.18



# data.table 기초 활용
DF <- data.frame(x = rep(c("a", "b", "c"), each = 3), y = c(1, 3, 6), v = 1:9)
DT <- data.table(x = rep(c("a", "b", "c"), each = 3), y = c(1, 3, 6), v = 1:9)
# data.frame은 data 형식으로 만들어지고 data.table은 value로 만들어집니다.
# 하지만 같은 결과를 얻을 수 있습니다.
DF
##   x y v
## 1 a 1 1
## 2 a 3 2
## 3 a 6 3
## 4 b 1 4
## 5 b 3 5
## 6 b 6 6
## 7 c 1 7
## 8 c 3 8
## 9 c 6 9
DT
##    x y v
## 1: a 1 1
## 2: a 3 2
## 3: a 6 3
## 4: b 1 4
## 5: b 3 5
## 6: b 6 6
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9





DT[2]  # DT의 2번째 row를 출력합니다.
##    x y v
## 1: a 3 2
DT[, v]  # v column을 출력합니다.
## [1] 1 2 3 4 5 6 7 8 9
DT[, list(v)]  # v column을 table형태로 출력합니다.
##    v
## 1: 1
## 2: 2
## 3: 3
## 4: 4
## 5: 5
## 6: 6
## 7: 7
## 8: 8
## 9: 9
DT[2:3, sum(v)]  # 원하는 row를 원하는 수식으로 연산할수있습니다.
## [1] 5
DT
##    x y v
## 1: a 1 1
## 2: a 3 2
## 3: a 6 3
## 4: b 1 4
## 5: b 3 5
## 6: b 6 6
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
DT[, 3, with = FALSE]  #원하는 column을 출력할수있습니다.(3번째 column)
##    v
## 1: 1
## 2: 2
## 3: 3
## 4: 4
## 5: 5
## 6: 6
## 7: 7
## 8: 8
## 9: 9
colNum = 2
DT[, colNum, with = FALSE]
##    y
## 1: 1
## 2: 3
## 3: 6
## 4: 1
## 5: 3
## 6: 6
## 7: 1
## 8: 3
## 9: 6
# data.table 에서 sorting할 column 지정하는 것입니다.
setkey(DT, x)
setkeyv(DT, "x")

# data.table에서 원하는 문자형 자료 찾기
DT["c"]
##    x y v
## 1: c 1 7
## 2: c 3 8
## 3: c 6 9
DT[x == "a"]
##    x y v
## 1: a 1 1
## 2: a 3 2
## 3: a 6 3
DT[x != "a"]  # a를 제외한 자료만 출력하기
##    x y v
## 1: b 1 4
## 2: b 3 5
## 3: b 6 6
## 4: c 1 7
## 5: c 3 8
## 6: c 6 9

# by로 지정된 변수기준으로 설정된 연산으로 새로운 변수를 만듭니다.
DT[, sum(v), by = x]
##    x V1
## 1: a  6
## 2: b 15
## 3: c 24
DT[, sum(v), by = key(DT)]
##    x V1
## 1: a  6
## 2: b 15
## 3: c 24
DT[, sum(v), by = y]
##    y V1
## 1: 1 12
## 2: 3 15
## 3: 6 18

# 지정된 값을 갖는 row를 이용하여 새로운 변수를 만듭니다.
DT["a", sum(v)]
##    x V1
## 1: a  6
DT[c("a", "b"), sum(v)]
##    x V1
## 1: a  6
## 2: b 15

X = data.table(c("b", "c"), foo = c(4, 2))
X
##    V1 foo
## 1:  b   4
## 2:  c   2
## 원하는 조건의 값을 뽑는 동시에 데이터 합치기 &새로운 변수 만들기 미리
## setkey로 기준이되는 변수를 설정하여야 합니다.
DT[X]
##    x y v foo
## 1: b 1 4   4
## 2: b 3 5   4
## 3: b 6 6   4
## 4: c 1 7   2
## 5: c 3 8   2
## 6: c 6 9   2
DT[X, sum(v)]
##    x V1
## 1: b 15
## 2: c 24
DT[X, mult = "first"]
##    x y v foo
## 1: b 1 4   4
## 2: c 1 7   2
DT[X, mult = "last"]
##    x y v foo
## 1: b 6 6   4
## 2: c 6 9   2
DT[X, sum(v) * foo]
##    x V1
## 1: b 60
## 2: c 48


setkey(DT, x, y)  #2개의 column key 지정합니다.
setkeyv(DT, c("x", "y"))

# 원하는 조건의 값을 찾습니다. 하지만 미리 위의 setkey를 설정한 후
# 진행하여야 합니다.
DT["a"]
##    x y v
## 1: a 1 1
## 2: a 3 2
## 3: a 6 3
DT[J("a")]  # same.
##    x y v
## 1: a 1 1
## 2: a 3 2
## 3: a 6 3
DT[list("a")]  # same
##    x y v
## 1: a 1 1
## 2: a 3 2
## 3: a 6 3
DT[.("a")]  # same
##    x y v
## 1: a 1 1
## 2: a 3 2
## 3: a 6 3

DT[J("a", 6)]  #2개의 조건을 만족하는 값을 출력합니다.
##    x y v
## 1: a 6 3
DT[.("a", 3)]
##    x y v
## 1: a 3 2
DT[J("a", 3:6)]  #조건의 만족하는 값을 출력합니다.
##    x y  v
## 1: a 3  2
## 2: a 4 NA
## 3: a 5 NA
## 4: a 6  3
DT[J("a", 3:6), nomatch = 0]  #missing value를 제거 합니다.
##    x y v
## 1: a 3 2
## 2: a 6 3
DT[J("a", 3:6), roll = TRUE]  #missing value에 대신 할값을 넣습니다.
##    x y v
## 1: a 3 2
## 2: a 4 2
## 3: a 5 2
## 4: a 6 3

## .SD : by로 지정된 변수의 부분집합을 구합니다.
DT[, sum(v), by = list(y%%2)]  #나머지를 이용하여 새로운 변수를 만듭니다.
##    y V1
## 1: 1 27
## 2: 0 18
DT[, .SD[2], by = x]  # x변수의 각각의 2번째 row의 부분집합을 만듭니다.
##    x y v
## 1: a 3 2
## 2: b 3 5
## 3: c 3 8
DT[, tail(.SD, 2), by = x]  #by로 지정된 각 x변수의 마지막 2번째 value를 출력합니다.
##    x y v
## 1: a 3 2
## 2: a 6 3
## 3: b 3 5
## 4: b 6 6
## 5: c 3 8
## 6: c 6 9
DT[, lapply(.SD, sum), by = x]  #apply 함수를 이용하여 조건에 맞는 부분집합을 만듭니다.
##    x  y  v
## 1: a 10  6
## 2: b 10 15
## 3: c 10 24

DT[, list(MySum = sum(v), MyMin = min(v), MyMax = max(v)), by = list(x, y%%2)]
##    x y MySum MyMin MyMax
## 1: a 1     3     1     2
## 2: a 0     3     3     3
## 3: b 1     9     4     5
## 4: b 0     6     6     6
## 5: c 1    15     7     8
## 6: c 0     9     9     9
# by를 이용하여 정렬할 변수에 조건을 만들어 새로운 변수를 만듭니다.


# 새로운 변수를 만들때 추가 조건은 새로 []를 이용하여 조건을 만듭니다.
DT[, sum(v), x][V1 < 20]
##    x V1
## 1: a  6
## 2: b 15
DT[, sum(v), x][order(-V1)]
##    x V1
## 1: c 24
## 2: b 15
## 3: a  6


# ':=' 문자형 변수인 x의 값인 'a','b','c'를 각각을 대상으로 원하는
# 연산을하여 새로운 변수로 column을 만들 수 있습니다.
DT[, `:=`(K, sum(y)), by = x]
##    x y v  K
## 1: a 1 1 10
## 2: a 3 2 10
## 3: a 6 3 10
## 4: b 1 4 10
## 5: b 3 5 10
## 6: b 6 6 10
## 7: c 1 7 10
## 8: c 3 8 10
## 9: c 6 9 10
# 원하는 조건을 만들어 빠르게 Data가 아닌 value값으로 새로운 변수를
# 만들수있습니다.
print(DT[, `:=`(z, 42L)])
##    x y v  K  z
## 1: a 1 1 10 42
## 2: a 3 2 10 42
## 3: a 6 3 10 42
## 4: b 1 4 10 42
## 5: b 3 5 10 42
## 6: b 6 6 10 42
## 7: c 1 7 10 42
## 8: c 3 8 10 42
## 9: c 6 9 10 42
print(DT[, `:=`(z, NULL)])  #변수를 지울수있습니다.
##    x y v  K
## 1: a 1 1 10
## 2: a 3 2 10
## 3: a 6 3 10
## 4: b 1 4 10
## 5: b 3 5 10
## 6: b 6 6 10
## 7: c 1 7 10
## 8: c 3 8 10
## 9: c 6 9 10
print(DT["a", `:=`(v, 42L)])
##    x y  v  K
## 1: a 1 42 10
## 2: a 3 42 10
## 3: a 6 42 10
## 4: b 1  4 10
## 5: b 3  5 10
## 6: b 6  6 10
## 7: c 1  7 10
## 8: c 3  8 10
## 9: c 6  9 10
print(DT["b", `:=`(v2, 84L)])
##    x y  v  K v2
## 1: a 1 42 10 NA
## 2: a 3 42 10 NA
## 3: a 6 42 10 NA
## 4: b 1  4 10 84
## 5: b 3  5 10 84
## 6: b 6  6 10 84
## 7: c 1  7 10 NA
## 8: c 3  8 10 NA
## 9: c 6  9 10 NA

# 마지막 []는 console창에 출력하기 위해 사용합니다.
DT[, `:=`(m, mean(v)), by = x][]
##    x y  v  K v2  m
## 1: a 1 42 10 NA 42
## 2: a 3 42 10 NA 42
## 3: a 6 42 10 NA 42
## 4: b 1  4 10 84  5
## 5: b 3  5 10 84  5
## 6: b 6  6 10 84  5
## 7: c 1  7 10 NA  8
## 8: c 3  8 10 NA  8
## 9: c 6  9 10 NA  8
DT[, .SD[which.min(v)], by = x][]
##    x y  v  K v2  m
## 1: a 1 42 10 NA 42
## 2: b 1  4 10 84  5
## 3: c 1  7 10 NA  8