data.table基础知识

#加载航班信息

#fread 快速文件阅读器

#使用data.table 亲自创建

#如果列是字符型,则不能转化成因子型(factor)

#data.table 不能设置和使用行名字。

> library(data.table)
> flights <- fread("flights14.csv")
> flights

> dim(flights)

 

> DT = data.table(ID = c("b","b","b","a","a","c"), a = 1:6, b = 7:12, c = 13:18)
> DT

   ID a  b  c
1:  b 1  7 13
2:  b 2  8 14
3:  b 3  9 15
4:  a 4 10 16
5:  a 5 11 17
6:  c 6 12 18
> class(DT$ID)
[1] "character"

> as.data.table()

> getOption("datatable.print.nrows")
[1] 100

 

#data.table 的基本形式,与sql语法作对比,便于理解

> DT[i, j, by]

 

##   R:      i                 j        by

## SQL:  where   select | update  group by

#Take DT, subset rows using i, then calculate j, grouped by by.

> ans <- flights[origin == "JFK" & month == 6L]
> dim(ans)

[1] 8422   17

 

选取行i

> flights[origin == "JFK" & month == 6L, ]#逗号可加可不加,data.frame中则必须要加

> ans <- flights[1:2]
> ans

> ans <- flights[order(origin, -dest)]# -dest 降序
> head(ans)

 

> odt = data.table(col = sample(1e7))
> t1 <- system.time(ans1 <- odt[base::order(col)]) ## uses order from base R
> t2 <- system.time(ans2 <- odt[order(col)]) ## uses data.table's forder#传统R自带包中的order与data.table中的order运行时间作对比
> (identical(ans1, ans2))  #比较两变量是否相同,相同返回TRUE,否则FALSE

[1] TRUE

 

#选取列j

> ans <- flights[, arr_delay]   #变量格式
> head(ans)

[1]  13  13   9 -26   1   0
> ans <- flights[, list(arr_delay)] #返回data.table格式
> head(ans)

   arr_delay
1:        13
2:        13
3:         9
4:       -26
5:         1
6:         0
> ans <- flights[, .(arr_delay, dep_delay)] #等同于ans <- flights[, list(arr_delay, dep_delay)]
> head(ans)

   arr_delay dep_delay
1:        13        14
2:        13        -3
3:         9         2
4:       -26        -8
5:         1         2
6:         0         4

#重命名

ans <- flights[, .(delay_arr = arr_delay, delay_dep = dep_delay)]

head(ans)

#关于j的计算

ans <- flights[, sum((arr_delay + dep_delay) < 0)]#[1] 141814 得到一个值 ,计算两列数值相加小于0的个案个数

ans <- flights[, .((arr_delay + dep_delay) < 0)]

table(ans)

 

#计算6月份以“JFK”为原产地机场的所有航班的平均到达和离开延误时间

ans <- flights[origin == "JFK" & month == 6L,.(m_arr = mean(arr_delay), m_dep = mean(dep_delay))] # 为什么month == 6L

ans

#       m_arr    m_dep

# 1: 5.839349 9.807884

 

#data.frame 的操作方式

flights_test<-as.data.frame(flights)

ansx<-apply(flights_test[which(origin %in% "JFK" & month %in% 6),c(5,7)],2,mean)

ansx

#dep_delay arr_delay

#9.807884  5.839349

 

#在6月份的“JFK”机场2014年有多少次旅行?

ans <- flights[origin == "JFK" & month == 6L, length(dest)] #同下

ans

# [1] 8422

ans <- flights[origin == "JFK" & month == 6L, .N] #.N返回查询的子集的行数

ans

# [1] 8422

nrow(flights[origin == "JFK" & month == 6L])#同上 低效

 

按名称引用列

#设置with = FALSE禁止引用列的功能,就像它们是变量一样,从而恢复“ data.frame模式”

ans <- flights[, c("arr_delay", "dep_delay"),with = FALSE]

head(ans)

 

ans <- flights[, !c("arr_delay", "dep_delay"), with = FALSE]#取消列的选择

ans <- flights[, -c("arr_delay", "dep_delay"), with = FALSE]#取消列的选择

#通过指定开始和结束列名year:day来选择

ans<-flights[,year: day,with = FALSE]

ans<-flights[,!(year: day),with = FALSE]

ans<-flights[,-(year: day),with = FALSE]

 

  使用分组 

ans <- flights[, .(.N), by = .(origin)]

ans

#origin     N

#1:    JFK 81483

#2:    LGA 84433

#3:    EWR 87400

#同上    ans<-flights[,.(.N),by="origin"]

 

#如果只有一列或表达式来引用j和by,我们可以删除.()符号。

ans <- flights[, list(.N), by = list(origin)]

ans <- flights[, .N, by = origin]

#如何计算每个起运机场的航空公司代码为“AA”的旅行次数?

ans <- flights[carrier == "AA", .N, by = origin]

ans

#怎样才能得到每origin, dest对货运代码为“AA”的旅行总次数?

ans <- flights[carrier == "AA", .N, by = .(origin,dest)]

#orig,dest运营商代码“AA”每月如何得到每对货物的平均到达和离开延迟?

ans <- flights[carrier == "AA",

               .(mean(arr_delay), mean(dep_delay)),

               by = .(origin, dest, month)]  #月份排序

 

ans <- flights[carrier == "AA",

               .(mean(arr_delay), mean(dep_delay)),

               keyby = .(origin, dest, month)]  #月份排序

ans

 

#对origin升序,dest降序,对结果进行重排列

ans <- flights[carrier == "AA", .N, by = .(origin, dest)][order(origin, -dest)]

 

链接[chain]

 

如:

 ans <- flights[carrier == "AA", .N, by = .(origin, dest)][order(origin, -dest)]

 head(ans, 10)

 

可以一直链接下去,形式如:DT[ ... ][ ... ][ ... ]

或者进行垂直链接:

DT[ ...

][ ...

][ ...

]

 

by中的表达式

 

by也可以接受表达式或列,如想知道哪一个航班起步较晚,但是提前达到,可以写成:

ans <- flights[, .N, .(dep_delay>0, arr_delay>0)]

ans

   dep_delay arr_delay      N
1:      TRUE      TRUE  72836
2:     FALSE      TRUE  34583
3:     FALSE     FALSE 119304
4:      TRUE     FALSE  26593

 

最后一行对应于dep_delay > 0 = TRUE和arr_delay > 0 = FALSE。我们可以看到,26593班航班起步晚,但提早(或按时)到达。

 

 

j 中含有多列--.SD

 

> DT
   ID a  b  c
1:  b 1  7 13
2:  b 2  8 14
3:  b 3  9 15
4:  a 4 10 16
5:  a 5 11 17
6:  c 6 12 18

 

> DT[,print(.SD),by=ID]
   a b  c
1: 1 7 13
2: 2 8 14
3: 3 9 15
   a  b  c
1: 4 10 16
2: 5 11 17
   a  b  c
1: 6 12 18
Empty data.table (0 rows) of 1 col: ID

 

.SD包含出分组以外的所有的列。可以用apply进行计算。

> DT[,lapply(.SD,mean),by=ID]
   ID   a    b    c
1:  b 2.0  8.0 14.0
2:  a 4.5 10.5 16.5
3:  c 6.0 12.0 18.0

因为apply()返回的就是列表格式,因此不需要再使用 “.()”.

 

指定想要计算的列的均值mean

 

使用参数 .SDcols()

 

flights[carrier == "AA",                       ## Only on trips with carrier "AA"

        lapply(.SD, mean),                     ## compute the mean

        by = .(origin, dest, month),           ## for every 'origin,dest,month'

        .SDcols = c("arr_delay", "dep_delay")] ## for just those specified in .SDcols

 

     origin dest month  arr_delay  dep_delay
  1:    JFK  LAX     1   6.590361 14.2289157
  2:    LGA  PBI     1  -7.758621  0.3103448
  3:    EWR  LAX     1   1.366667  7.5000000
  4:    JFK  MIA     1  15.720670 18.7430168
  5:    JFK  SEA     1  14.357143 30.7500000
 ---                                       
196:    LGA  MIA    10  -6.251799 -1.4208633
197:    JFK  MIA    10  -1.880184  6.6774194
198:    EWR  PHX    10  -3.032258 -4.2903226
199:    JFK  MCO    10 -10.048387 -1.6129032
200:    JFK  DCA    10  16.483871 15.5161290

 

.SD 每个组的子集

 

> ans <- flights[, head(.SD, 2), by = month]
> ans

提取每个月的前两个的子集

1

1

2

2

3

3

 

保持j的灵活性

 

DT[,.(val=c(a,b)),by=ID]
    ID val
 1:  b   1
 2:  b   2
 3:  b   3
 4:  b   7
 5:  b   8
 6:  b   9
 7:  a   4
 8:  a   5
 9:  a  10
10:  a  11
11:  c   6
12:  c  12

 

DT[,.(val=list(c(a,b))),by=ID]
   ID         val
1:  b 1,2,3,7,8,9
2:  a  4, 5,10,11
3:  c        6,12

 

总结

 

data.table 的语法形式是:data.table[i,j,by]

 

使用i:

1.可以采用与数据框类似的提取子集的方式

2.使用order对data.table进行排序

 

使用j:

1.选择列的data.table 方式:DT[,.(colA,colB)]

2.选择data.frame的方式:DT[,c("colA","colB"),with = FALSE]

3.在列上计算:DT[,.(sum(colA),mean(colB))]

4.如有必要提供列名:DT[,.(sA=sum(colA),mB=mean(colB))]

5.结合i:DT[colA > value,sum(colB)]

 

 

使用by:

1. `DT[, lapply(.SD, fun), by = ..., .SDcols = ...]

--对SDcols中选择的所有列进行函数fun计算,通过by分组进行分组计算

2. `DT[, head(.SD, 2), by = ...] --返回每组的前两行数据

3. `DT[col > val, head(.SD, 1), by = ...]`

---先选择满足col > val的行,然后通过by进行分组,最后提取每组中的第一行数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值