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에서 여러 장의 테이블을 읽은 다음 스택 하는 별도의 예제가 있습니다 .