data.table
고쳐 쓰기, 스태킹 및 분할
수색…
비고
공식 비 네트 인 "data.tables를 사용하여 효율적으로 고쳐 쓰기" 는이 주제에 대한 최고의 소개입니다.
많은 재구성 작업에는 길고 넓은 포맷 간의 이동이 필요합니다.
- 넓은 데이터는 각 열이 별도의 변수를 나타내는 데이터이고 별도의 관측을 나타내는 행입니다.
- 긴 데이터는 양식 ID | 변수 | 각 행은 관찰 변수 쌍을 나타냅니다.
data.table로 녹여 주조하다.
data.table
은 효율적이고 쉽게 데이터를 재구성 할 수있는 다양한 가능성을 제공합니다
예를 들어, 길고 넓은 형태로 재 형성하는 동안 여러 변수를 value.var
및 fun.aggregate
매개 변수에 동시에 전달할 수 있습니다
library(data.table) #v>=1.9.6
DT <- data.table(mtcars)
길고 넓은
dcast(DT, gear ~ cyl, value.var = c("disp", "hp"), fun = list(mean, sum))
gear disp_mean_4 disp_mean_6 disp_mean_8 hp_mean_4 hp_mean_6 hp_mean_8 disp_sum_4 disp_sum_6 disp_sum_8 hp_sum_4 hp_sum_6 hp_sum_8
1: 3 120.100 241.5 357.6167 97 107.5 194.1667 120.1 483.0 4291.4 97 215 2330
2: 4 102.625 163.8 NaN 76 116.5 NaN 821.0 655.2 0.0 608 466 0
3: 5 107.700 145.0 326.0000 102 175.0 299.5000 215.4 145.0 652.0 204 175 599
이것은 gear
를 인덱스 열로 설정하는 반면, mean
및 sum
은 모든 gear
및 cyl
조합에 대해 disp
및 hp
대해 계산됩니다. 일부 조합이 존재하지 않는 경우 na.rm = TRUE
( mean
및 sum
함수에 전달 na.rm = TRUE
와 같은 추가 매개 변수를 지정하거나 빌트인 fill
인수를 지정할 수 있습니다. 또한 여백을 추가하고 누락 된 조합을 삭제하고 데이터를 부분 집합으로 지정할 수 있습니다. ?data.table::dcast
와이드 투 오랫동안
long에서 reshaping하는 동안 정규 표현식을 사용하여 열을 measure.vars
매개 변수에 전달할 수 있습니다 (예 :
print(melt(DT, c("cyl", "gear"), measure = patterns("^d", "e")), n = 10)
cyl gear variable value1 value2
1: 6 4 1 160.00 16.46
2: 6 4 1 160.00 17.02
3: 4 4 1 108.00 18.61
4: 6 3 1 258.00 19.44
5: 8 3 1 360.00 17.02
---
60: 4 5 2 3.77 5.00
61: 8 5 2 4.22 5.00
62: 6 5 2 3.62 5.00
63: 8 5 2 3.54 5.00
64: 4 4 2 4.11 4.00
이것은 것이다 melt
하여 데이터 cyl
및 gear
로 시작하는 변수에 대한 모든 값하면서 인덱스 열 등을 d
( disp
및 drat
)으로 존재할 것이다 value1
과 문자가 포함 된 변수의 값 e
그들 ( qsec
및 gear
)가 value2
열에 표시됩니다.
또한 지정하면서 결과에 모든 열 이름을 바꿀 수 있습니다 variable.name
및 value.name
인수 또는 당신이 원하는 경우 결정 character
열이 자동으로 변환 할 factor
지정 동안의 여부를 variable.factor
및 value.factor
인수를. 더 많은 것을보기 ?data.table::melt
`data.table`을 사용하여 변형
data.table
은 reshape2
의 melt
& dcast
함수를 확장합니다.
( 참고 자료 : data.tables를 사용한 효율적인 재 형성 )
library(data.table)
## generate some data
dt <- data.table(
name = rep(c("firstName", "secondName"), each=4),
numbers = rep(1:4, 2),
value = rnorm(8)
)
dt
# name numbers value
# 1: firstName 1 -0.8551881
# 2: firstName 2 -1.0561946
# 3: firstName 3 0.2671833
# 4: firstName 4 1.0662379
# 5: secondName 1 -0.4771341
# 6: secondName 2 1.2830651
# 7: secondName 3 -0.6989682
# 8: secondName 4 -0.6592184
장황함
dcast(data = dt,
formula = name ~ numbers,
value.var = "value")
# name 1 2 3 4
# 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078
# 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814
여러 열 ( data.table
1.9.6 현재)
## add an extra column
dt[, value2 := value * 2]
## cast multiple value columns
dcast(data = dt,
formula = name ~ numbers,
value.var = c("value", "value2"))
# name value_1 value_2 value_3 value_4 value2_1 value2_2 value2_3 value2_4
# 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078 0.3672866 -1.6712572 3.190562 0.6590155
# 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814 -1.6409368 0.9748581 1.476649 1.1515627
와이드에서 롱
## use a wide data.table
dt <- fread("name 1 2 3 4
firstName 0.1836433 -0.8356286 1.5952808 0.3295078
secondName -0.8204684 0.4874291 0.7383247 0.5757814", header = T)
dt
# name 1 2 3 4
# 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078
# 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814
## melt to long, specifying the id column, and the name of the columns
## in the resulting long data.table
melt(dt,
id.vars = "name",
variable.name = "numbers",
value.name = "myValue")
# name numbers myValue
# 1: firstName 1 0.1836433
# 2: secondName 1 -0.8204684
# 3: firstName 2 -0.8356286
# 4: secondName 2 0.4874291
# 5: firstName 3 1.5952808
# 6: secondName 3 0.7383247
# 7: firstName 4 0.3295078
# 8: secondName 4 0.5757814
용융물을 사용하여 넓은 것에서 긴 것으로
녹는 : 기본 사항
용융은 데이터를 넓은 형식에서 긴 형식으로 변환하는 데 사용됩니다.
광범위한 데이터 세트로 시작 :
DT = data.table(ID = letters[1:3], Age = 20:22, OB_A = 1:3, OB_B = 4:6, OB_C = 7:9)
data.table의 melt
함수를 사용하여 데이터를 녹일 수 있습니다. long 형식의 다른 data.table을 반환합니다.
melt(DT, id.vars = c("ID","Age"))
1: a 20 OB_A 1
2: b 21 OB_A 2
3: c 22 OB_A 3
4: a 20 OB_B 4
5: b 21 OB_B 5
6: c 22 OB_B 6
7: a 20 OB_C 7
8: b 21 OB_C 8
9: c 22 OB_C 9
class(melt(DT, id.vars = c("ID","Age")))
# "data.table" "data.frame"
id.vars
매개 변수에 설정되지 않은 모든 열은 변수로 간주됩니다. 또는 measure.vars
인수를 사용하여 명시 적으로 설정할 수 있습니다.
melt(DT, measure.vars = c("OB_A","OB_B","OB_C"))
ID Age variable value
1: a 20 OB_A 1
2: b 21 OB_A 2
3: c 22 OB_A 3
4: a 20 OB_B 4
5: b 21 OB_B 5
6: c 22 OB_B 6
7: a 20 OB_C 7
8: b 21 OB_C 8
9: c 22 OB_C 9
이 경우 measure.vars
에 설정되지 않은 모든 열은 ID로 간주됩니다.
둘 다 명시 적으로 설정하면 선택한 열만 반환됩니다.
melt(DT, id.vars = "ID", measure.vars = c("OB_C"))
ID variable value
1: a OB_C 7
2: b OB_C 8
3: c OB_C 9
결과의 변수 및 값 명명
variable.name
과 value.name
사용하여 반환 된 테이블의 열 이름을 조작 할 수 있습니다.
melt(DT,
id.vars = c("ID"),
measure.vars = c("OB_C"),
variable.name = "Test",
value.name = "Result"
)
ID Test Result
1: a OB_C 7
2: b OB_C 8
3: c OB_C 9
결과에서 측정 변수의 유형 설정
기본적으로 measure.vars
을 사용하면 모든 measure.vars
가 인수로 변환됩니다.
M_DT <- melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"))
class(M_DT[, variable])
# "factor"
대신 문자로 설정하려면 variable.factor
인수를 사용하십시오.
M_DT <- melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"), variable.factor = FALSE)
class(M_DT[, variable])
# "character"
값은 일반적으로 원본 열의 데이터 형식을 상속합니다.
class(DT[, value])
# "integer"
class(M_DT[, value])
# "integer"
충돌이 있으면 데이터 유형이 강제됩니다. 예 :
M_DT <- melt(DT,id.vars = c("Age"), measure.vars = c("ID","OB_C"))
class(M_DT[, value])
# "character"
용융 될 때, 요인 변수는 문자 유형으로 강요됩니다 :
DT[, OB_C := factor(OB_C)]
M_DT <- melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"))
class(M_DT)
# "character"
이를 방지하고 초기 입력을 유지하려면 value.factor
인수를 사용하십시오.
M_DT <- melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"), value.factor = TRUE)
class(M_DT)
# "factor"
누락 된 값 처리
기본적으로 모든 NA
값은 용융 데이터에 보존됩니다
DT = data.table(ID = letters[1:3], Age = 20:22, OB_A = 1:3, OB_B = 4:6, OB_C = c(7:8,NA))
melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"))
ID variable value
1: a OB_C 7
2: b OB_C 8
3: c OB_C NA
이러한 데이터를 데이터에서 제거해야하는 경우 na.rm = TRUE
설정하십시오.
melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"), na.rm = TRUE)
ID variable value
1: a OB_C 7
2: b OB_C 8
dcast를 사용하여 긴 형식에서 넓은 형식으로 이동
주조 : 기본 사항
형변환은 데이터를 긴 형식에서 넓은 형식으로 변환하는 데 사용됩니다.
긴 데이터 세트로 시작 :
DT = data.table(ID = rep(letters[1:3],3), Age = rep(20:22,3), Test = rep(c("OB_A","OB_B","OB_C"), each = 3), Result = 1:9)
dcast
의 dcast
함수를 사용하여 데이터를 캐스팅 할 수 있습니다. 이렇게하면 와이드 형식으로 또 다른 data.table을 반환합니다.
dcast(DT, formula = ID ~ Test, value.var = "Result")
ID OB_A OB_B OB_C
1: a 1 4 7
2: b 2 5 8
3: c 3 6 9
class(dcast(DT, formula = ID ~ Test, value.var = "Result"))
[1] "data.table" "data.frame"
값 캐스팅
value.var
인수는 적절한 캐스트에 필요합니다. 제공되지 않으면 dcast는 데이터를 기반으로 가정을합니다.
dcast(DT, formula = ID ~ Test, value.var = "Result")
ID OB_A OB_B OB_C
1: a 1 4 7
2: b 2 5 8
3: c 3 6 9
ID OB_A OB_B OB_C
1: a 20 20 20
2: b 21 21 21
3: c 22 22 22
여러 개의 value.var
가 목록에 제공 될 수 있습니다.
dcast(DT, formula = ID ~ Test, value.var = list("Result","Age"))
ID Result_OB_A Result_OB_B Result_OB_C Age_OB_A Age_OB_B Age_OB_C
1: a 1 4 7 20 20 20
2: b 2 5 8 21 21 21
3: c 3 6 9 22 22 22
공식
전송은 dcast
의 수식 인수를 사용하여 제어됩니다. 이것은 ROWS ~ COLUMNS 형식입니다.
dcast(DT, formula = ID ~ Test, value.var = "Result")
ID OB_A OB_B OB_C
1: a 1 4 7
2: b 2 5 8
3: c 3 6 9
dcast(DT, formula = Test ~ ID, value.var = "Result")
Test a b c
1: OB_A 1 2 3
2: OB_B 4 5 6
3: OB_C 7 8 9
행과 열을 모두 확장하려면 +
dcast(DT, formula = ID + Age ~ Test, value.var = "Result")
ID Age OB_A OB_B OB_C
1: a 20 1 4 7
2: b 21 2 5 8
3: c 22 3 6 9
dcast(DT, formula = ID ~ Age + Test, value.var = "Result")
ID 20_OB_A 20_OB_B 20_OB_C 21_OB_A 21_OB_B 21_OB_C 22_OB_A 22_OB_B 22_OB_C
1: a 1 4 7 NA NA NA NA NA NA
2: b NA NA NA 2 5 8 NA NA NA
3: c NA NA NA NA NA NA 3 6 9
#order is important
dcast(DT, formula = ID ~ Test + Age, value.var = "Result")
ID OB_A_20 OB_A_21 OB_A_22 OB_B_20 OB_B_21 OB_B_22 OB_C_20 OB_C_21 OB_C_22
1: a 1 NA NA 4 NA NA 7 NA NA
2: b NA 2 NA NA 5 NA NA 8 NA
3: c NA NA 3 NA NA 6 NA NA 9
주조는 종종 데이터에 관찰이없는 셀을 만들 수 있습니다. 기본적으로 위와 같이 NA
로 표시됩니다. 이것을 fill=
인수로 대체 할 수 있습니다.
dcast(DT, formula = ID ~ Test + Age, value.var = "Result", fill = 0)
ID OB_A_20 OB_A_21 OB_A_22 OB_B_20 OB_B_21 OB_B_22 OB_C_20 OB_C_21 OB_C_22
1: a 1 0 0 4 0 0 7 0 0
2: b 0 2 0 0 5 0 0 8 0
3: c 0 0 3 0 0 6 0 0 9
수식 개체에서 두 개의 특수 변수를 사용할 수도 있습니다
-
.
다른 변수를 나타내지 않습니다. -
...
는 다른 모든 변수를 나타냅니다.
dcast(DT, formula = Age ~ ., value.var = "Result")
Age .
1: 20 3
2: 21 3
3: 22 3
dcast(DT, formula = ID + Age ~ ..., value.var = "Result")
ID Age OB_A OB_B OB_C
1: a 20 1 4 7
2: b 21 2 5 8
3: c 22 3 6 9
우리의 가치 집계 .var
하나의 단계에서 값을 캐스팅하고 집계 할 수도 있습니다. 이 경우 우리는 나이와 ID의 각 교차점에서 세 가지 관찰을합니다. 우리가 원하는 집계를 설정하기 위해 fun.aggregate
인수를 사용합니다.
#length
dcast(DT, formula = ID ~ Age, value.var = "Result", fun.aggregate = length)
ID 20 21 22
1: a 3 0 0
2: b 0 3 0
3: c 0 0 3
#sum
dcast(DT, formula = ID ~ Age, value.var = "Result", fun.aggregate = sum)
ID 20 21 22
1: a 12 0 0
2: b 0 15 0
3: c 0 0 18
#concatenate
dcast(DT, formula = ID ~ Age, value.var = "Result", fun.aggregate = function(x){paste(x,collapse = "_")})
ID 20 21 22
1: a 1_4_7
2: b 2_5_8
3: c 3_6_9
fun.aggregate
에 여러 함수를 사용하기 위해 목록을 전달할 수도 있습니다.
dcast(DT, formula = ID ~ Age, value.var = "Result", fun.aggregate = list(sum,length))
ID Result_sum_20 Result_sum_21 Result_sum_22 Result_length_20 Result_length_21 Result_length_22
1: a 12 0 0 3 0 0
2: b 0 15 0 0 3 0
3: c 0 0 18 0 0 3
둘 이상의 함수와 하나 이상의 값을 전달하면 value.vars의 벡터를 전달하여 모든 조합을 계산할 수 있습니다.
dcast(DT, formula = ID ~ Age, value.var = c("Result","Test"), fun.aggregate = list(function(x){paste0(x,collapse = "_")},length))
ID Result_function_20 Result_function_21 Result_function_22 Test_function_20 Test_function_21 Test_function_22 Result_length_20 Result_length_21
1: a 1_4_7 OB_A_OB_B_OB_C 3 0
2: b 2_5_8 OB_A_OB_B_OB_C 0 3
3: c 3_6_9 OB_A_OB_B_OB_C 0 0
Result_length_22 Test_length_20 Test_length_21 Test_length_22
1: 0 3 0 0
2: 0 0 3 0
3: 3 0 0 3
각 쌍은 value1_formula1, value1_formula2, ... , valueN_formula(N-1), valueN_formulaN
순서로 계산됩니다.
또는 'value.var'를 목록으로 전달하여 값과 함수를 일대일로 평가할 수 있습니다.
dcast(DT, formula = ID ~ Age, value.var = list("Result","Test"), fun.aggregate = list(function(x){paste0(x,collapse = "_")},length))
ID Result_function_20 Result_function_21 Result_function_22 Test_length_20 Test_length_21 Test_length_22
1: a 1_4_7 3 0 0
2: b 2_5_8 0 3 0
3: c 3_6_9 0 0 3
결과의 열 이름 지정
기본적으로 열 이름 구성 요소는 밑줄 _
됩니다. sep=
인수를 사용하여 수동으로 재정의 할 수 있습니다.
dcast(DT, formula = Test ~ ID + Age, value.var = "Result")
Test a_20 b_21 c_22
1: OB_A 1 2 3
2: OB_B 4 5 6
3: OB_C 7 8 9
dcast(DT, formula = Test ~ ID + Age, value.var = "Result", sep = ",")
Test a,20 b,21 c,22
1: OB_A 1 2 3
2: OB_B 4 5 6
3: OB_C 7 8 9
이것은 우리가 사용하는 fun.aggregate
또는 value.var
을 분리합니다 :
dcast(DT, formula = Test ~ ID + Age, value.var = "Result", fun.aggregate = c(sum,length), sep = ",")
Test Result,sum,a,20 Result,sum,b,21 Result,sum,c,22 Result,length,a,20 Result,length,b,21 Result,length,c,22
1: OB_A 1 2 3 1 1 1
2: OB_B 4 5 6 1 1 1
3: OB_C 7 8 9 1 1 1
rbindlist를 사용하여 여러 테이블 쌓기
R의 일반적인 자만은 다음 줄을 따라 간다.
DT1
,DT2
, ...,DT11
과 같은 이름을 가진 많은 관련 테이블을 가지고 있어서는 안됩니다. 개체를 반복적으로 읽고 이름에 할당하는 것은 지저분합니다. 해결책은 데이터 테이블 목록입니다!
그러한 목록은 다음과 같습니다.
set.seed(1)
DT_list = lapply(setNames(1:3, paste0("D", 1:3)), function(i)
data.table(id = 1:2, v = sample(letters, 2)))
$D1
id v
1: 1 g
2: 2 j
$D2
id v
1: 1 o
2: 2 w
$D3
id v
1: 1 f
2: 2 w
또 다른 관점은이 테이블을 쌓아서 하나의 테이블로 저장해야한다는 것입니다. rbindlist
사용하는 것은 간단합니다.
DT = rbindlist(DT_list, id="src")
src id v
1: D1 1 g
2: D1 2 j
3: D2 1 o
4: D2 2 w
5: D3 1 f
6: D3 2 w
이 형식은 data.table 구문을 사용하는 것이 훨씬 더 의미가 있습니다. "그룹 별"연산은 일반적이며 직관적입니다.
좀 더 자세히 살펴 보려면 Gregor의 대답 을 시작하는 것이 좋습니다. 물론 체크 아웃 ?rbindlist
, 물론. CSV에서 여러 장의 테이블을 읽은 다음 스택 하는 별도의 예제가 있습니다 .