r - xlabel - tick size ggplot2




data.table의 모양을 바꾸는 적절한/가장 빠른 방법 (3)

이 기능은 위의 Zach의 대답에서 볼 수 있듯이 이제 data.table (1.8.11 버전)에서 구현됩니다.

방금 Arun의 코드를 보았습니다. 그래서 나는 data.table 솔루션이 있다고 생각한다. 이 문제에 적용 :

library(data.table)
set.seed(1234)
DT <- data.table(x=rep(c(1,2,3),each=1e6), 
                  y=c("A","B"), 
                  v=sample(1:100,12))

out <- DT[,list(SUM=sum(v)),by=list(x,y)]
# edit (mnel) to avoid setNames which creates a copy
# when calling `names<-` inside the function
out[, as.list(setattr(SUM, 'names', y)), by=list(x)]
})
   x        A        B
1: 1 26499966 28166677
2: 2 26499978 28166673
3: 3 26500056 28166650

이것은 DWin의 접근 방식과 동일한 결과를 제공합니다.

tapply(DT$v,list(DT$x, DT$y), FUN=sum)
         A        B
1 26499966 28166677
2 26499978 28166673
3 26500056 28166650

또한 빠릅니다.

system.time({ 
   out <- DT[,list(SUM=sum(v)),by=list(x,y)]
   out[, as.list(setattr(SUM, 'names', y)), by=list(x)]})
##  user  system elapsed 
## 0.64    0.05    0.70 
system.time(tapply(DT$v,list(DT$x, DT$y), FUN=sum))
## user  system elapsed 
## 7.23    0.16    7.39 

최신 정보

이 솔루션은 균형이 맞지 않은 데이터 세트 (예 : 일부 조합이 존재하지 않음)에서도 작동하기 때문에 먼저 데이터 테이블에 입력해야합니다.

library(data.table)
set.seed(1234)
DT <- data.table(x=c(rep(c(1,2,3),each=4),3,4), y=c("A","B"), v=sample(1:100,14))

out <- DT[,list(SUM=sum(v)),by=list(x,y)]
setkey(out, x, y)

intDT <- expand.grid(unique(out[,x]), unique(out[,y]))
setnames(intDT, c("x", "y"))
out <- out[intDT]

out[, as.list(setattr(SUM, 'names', y)), by=list(x)]

개요

위의 주석과 결합하여 다음은 1 행 솔루션입니다.

DT[, sum(v), keyby = list(x,y)][CJ(unique(x), unique(y)), allow.cartesian = T][,
   setNames(as.list(V1), paste(y)), by = x]

또한 단순히 합계 이상의 값을 갖도록 수정하는 것이 쉽습니다 (예 :

DT[, list(sum(v), mean(v)), keyby = list(x,y)][CJ(unique(x), unique(y)), allow.cartesian = T][,
   setNames(as.list(c(V1, V2)), c(paste0(y,".sum"), paste0(y,".mean"))), by = x]
#   x A.sum B.sum   A.mean B.mean
#1: 1    72   123 36.00000   61.5
#2: 2    84   119 42.00000   59.5
#3: 3   187    96 62.33333   48.0
#4: 4    NA    81       NA   81.0

R에 데이터 표 가 있습니다.

library(data.table)
set.seed(1234)
DT <- data.table(x=rep(c(1,2,3),each=4), y=c("A","B"), v=sample(1:100,12))
DT
      x y  v
 [1,] 1 A 12
 [2,] 1 B 62
 [3,] 1 A 60
 [4,] 1 B 61
 [5,] 2 A 83
 [6,] 2 B 97
 [7,] 2 A  1
 [8,] 2 B 22
 [9,] 3 A 99
[10,] 3 B 47
[11,] 3 A 63
[12,] 3 B 49

data.table의 그룹에 의해 변수 v를 쉽게 합할 수 있습니다.

out <- DT[,list(SUM=sum(v)),by=list(x,y)]
out
     x  y SUM
[1,] 1 A  72
[2,] 1 B 123
[3,] 2 A  84
[4,] 2 B 119
[5,] 3 A 162
[6,] 3 B  96

그러나 그룹 (y)을 행이 아니라 열로 유지하려고합니다. 나는 이것을 사용하여 이것을 할 수있다 :

out <- reshape(out,direction='wide',idvar='x', timevar='y')
out
     x SUM.A SUM.B
[1,] 1    72   123
[2,] 2    84   119
[3,] 3   162    96

데이터를 집계 한 후 데이터를 다시 만드는 더 효율적인 방법이 있습니까? data.table 작업을 사용하여 이러한 작업을 하나의 단계로 결합 할 수있는 방법이 있습니까?


Data.table 객체는 'data.frame'에서 상속되므로 tapply를 사용할 수 있습니다.

> tapply(DT$v,list(DT$x, DT$y), FUN=sum)
   AA  BB
a  72 123
b  84 119
c 162  96

reshape2 라이브러리의 dcast 를 사용할 수 있습니다. 여기에 코드가있다.

# DUMMY DATA
library(data.table)
mydf = data.table(
  x = rep(1:3, each = 4),
  y = rep(c('A', 'B'), times = 2),
  v = rpois(12, 30)
)

# USE RESHAPE2
library(reshape2)
dcast(mydf, x ~ y, fun = sum, value_var = "v")

참고 : 해결책은 훨씬 빠릅니다.







data.table