dplyr和data.table

  • .加载包
library(dplyr)
library(data.table)
library(lubridate)
library(jsonlite)
library(tidyr)
library(ggplot2)
library(compare)

使用jsonlite包中的fromJSON函数来下载数据集的JSON格式数据。

spending=fromJSON("https://data.medicare.gov/api/views/nrth-mfg3/rows.json?accessType=DOWNLOAD")
names(spending)
  • .数据处理
meta <- spending$meta
hospital_spending <- data.frame(spending$data)
colnames(hospital_spending) <- make.names(meta$view$columns$name)
## 查看数据
glimpse(hospital_spending)
# select列筛选
hospital_spending <- select(hospital_spending,-c(sid:meta))
glimpse(hospital_spending)

导入的所有数据列都是因子型数据。
下面我们将列中数据为数值的列改为数值型数据:

#因子型到数值型:先as.character再as.numeric

cols = 6:11  #需要改变数据类型的列
## 这里操作可以把需要改变的列作为一个向量变量
hospital_spending[,cols] <- lapply(hospital_spending[,cols],as.character)
hospital_spending[,cols] <- lapply(hospital_spending[,cols],as.numeric)

最后两列数据分别是数据收集的起始日期和结束日期。
使用lubridate包来纠正这两列的数据类型:

cols = 12:13;
hospital_spending[,cols] <- lapply(hospital_spending[,cols],ymd_hms)

检查数据列是否是我们想要的数据类型:

sapply(hospital_spending,class)    #sapply的用法

  • .创建data.table类型数据

使用data.table函数创建data.table类型数据:

class(hospital_spending)

hospital_spending_DT <- data.table(hospital_spending)
class(hospital_spending_DT)
  • .选取数据集的某些列

对于选取数据列,我们可以使用dplyr包中的select函数。
另一方面,我们只需在data.table中指定对应的列名即可。

选取一个变量

from_dplyr <- select(hospital_spending,Hospital_Name)
from_data_table <- hospital_spending_DT[,.(Hospital_Name)]

####from_data_table <- hospital_spending_DT[,Hospital_Name]
##直接这样也是可以的

对比下dplyr和data.table给出的结果是否相同:

compare(from_dplyr,from_data_table,allowAll = TRUE)

删除一个变量

from_dplyr <- select(hospital_spending,-Hospital_Name)
from_data_table <- hospital_spending_DT[,Hospital_Name := NULL]
####另一种写法
#from_data_table = hospital_spending_DT[,!c("Hospital.Name"),with=FALSE]

compare(from_dplyr,from_data_table,allowAll = TRUE)

对copy()函数所复制的输入对象得到的引用执行任何操作都不会对原始数据对象产生任何影响。如下所示:

DT=copy(hospital_spending_DT)
"Hospital_Name"%in% names(DT)

#删除其中一列
DT <- DT[,!c("Hospital_Name"),with = FALSE]
"Hospital_Name"%in% names(DT)   #验证是不是在里面

删除多个变量

DT=copy(hospital_spending_DT)

DT=DT[,c("Hospital_Name","State","Measure.Start.Date","Measure.End.Date"):=NULL] 

c("Hospital_Name","State","Measure.Start.Date","Measure.End.Date") %in% names(DT)

选取多个变量

from_dplyr = select(hospital_spending, Hospital.Name,State,Measure.Start.Date,Measure.End.Date)
from_data_table = hospital_spending_DT[,.(Hospital.Name,State,Measure.Start.Date,Measure.End.Date)]
compare(from_dplyr,from_data_table, allowAll=TRUE)
TRUE
dropped attributes 

删除多个变量

现在,我们要删除hospital_spending数据框和data.table类型数据hospital_spending_DT中的变量Hospital.Name,State,Measure.Start.Date,Measure.End.Date:

from_dplyr = select(hospital_spending, -c(Hospital.Name,State,Measure.Start.Date,Measure.End.Date))
from_data_table = hospital_spending_DT[,!c("Hospital.Name","State","Measure.Start.Date","Measure.End.Date"),with=FALSE]
compare(from_dplyr,from_data_table, allowAll=TRUE)
TRUE
dropped attributes

dplyr包中有contains(),starts_with(),ends_with()三个函数,它们可以跟select()函数一起结合使用。对于data.table,我们则可以使用正则表达式。下面我们将选取所有列名包含字符“Date”的列,示例如下:

from_dplyr = select(hospital_spending,contains("Date"))
from_data_table = subset(hospital_spending_DT,select=grep("Date",names(hospital_spending_DT)))
compare(from_dplyr,from_data_table, allowAll=TRUE)
names(from_dplyr)

重命名列名

setnames(hospital_spending_DT,c("Hospital.Name", "Measure.Start.Date","Measure.End.Date"), c("Hospital","Start_Date","End_Date"))

names(hospital_spending_DT)

"Hospital" "Provider.Number." "State" "Period" "Claim.Type" "Avg.Spending.Per.Episode..Hospital." "Avg.Spending.Per.Episode..State." "Avg.Spending.Per.Episode..Nation." "Percent.of.Spending..Hospital." "Percent.of.Spending..State." "Percent.of.Spending..Nation." "Start_Date" "End_Date" 

hospital_spending = rename(hospital_spending,Hospital= Hospital.Name, Start_Date=Measure.Start.Date,End_Date=Measure.End.Date)

compare(hospital_spending,hospital_spending_DT, allowAll=TRUE)

TRUE
  dropped attributes

筛选行

对于数据集特定行的筛选,我们可以使用dplyr包中的filter函数,它通过可能包含正则表达式的逻辑语句来实现该功能。在data.table中,我们只需使用逻辑语句就可以了。

对单个变量进行筛选

# selecting rows for California
from_dplyr = filter(hospital_spending,State=='CA') 

from_data_table = hospital_spending_DT[State=='CA']

compare(from_dplyr,from_data_table, allowAll=TRUE)

TRUE
  dropped attributes

对多个变量进行筛选

from_dplyr = filter(hospital_spending,State=='CA' & Claim.Type!="Hospice") 
from_data_table = hospital_spending_DT[State=='CA' & Claim.Type!="Hospice"]

compare(from_dplyr,from_data_table, allowAll=TRUE)

TRUE
  dropped attributes
from_dplyr = filter(hospital_spending,State %in% c('CA','MA',"TX")) 
from_data_table = hospital_spending_DT[State %in% c('CA','MA',"TX")]

unique(from_dplyr$State)
CA MA TX 

compare(from_dplyr,from_data_table, allowAll=TRUE)

TRUE
dropped attributes

数据排序

我们使用dplyr包中的arrange()函数对数据行进行排序,可以实现对一个或多个变量的数据行进行排序。如果想实现降序,需使用如下代码所示的desc()函数。以下示例演示了如何对数据行进行升序和降序排序:

#升序 
from_dplyr = arrange(hospital_spending, State)
from_data_table = setorder(hospital_spending_DT, State)

compare(from_dplyr,from_data_table, allowAll=TRUE)
#降序 
from_dplyr = arrange(hospital_spending, desc(State))
from_data_table = setorder(hospital_spending_DT, -State)

compare(from_dplyr,from_data_table, allowAll=TRUE)

对多变量进行排序

以下代码实现了State变量升序,End_Date变量降序排序:

from_dplyr = arrange(hospital_spending, State,desc(End_Date))
from_data_table = setorder(hospital_spending_DT, State,-End_Date)

compare(from_dplyr,from_data_table, allowAll=TRUE)

添加或更新列

在dplyr包中,使用mutate()函数来添加新列。在data.table包中,我们可以使用:=引用来添加或更新列:

from_dplyr = mutate(hospital_spending, diff=Avg.Spending.Per.Episode..State. - Avg.Spending.Per.Episode..Nation.)
from_data_table = copy(hospital_spending_DT)
from_data_table = from_data_table[,diff := Avg.Spending.Per.Episode..State. - Avg.Spending.Per.Episode..Nation.]
compare(from_dplyr,from_data_table, allowAll=TRUE)


from_dplyr = mutate(hospital_spending, diff1=Avg.Spending.Per.Episode..State. - Avg.Spending.Per.Episode..Nation.,diff2=End_Date-Start_Date)
from_data_table = copy(hospital_spending_DT)
from_data_table = from_data_table[,c("diff1","diff2") := list(Avg.Spending.Per.Episode..State. - Avg.Spending.Per.Episode..Nation.,diff2=End_Date-Start_Date)]
compare(from_dplyr,from_data_table, allowAll=TRUE)

数据汇总

我们可以使用dplyr包中的summarise()函数来创建概括性统计量:

summarize(hospital_spending,mean=mean(Avg.Spending.Per.Episode..Nation.))
mean 1820.409

hospital_spending_DT[,.(mean=mean(Avg.Spending.Per.Episode..Nation.))]
mean 1820.409

summarize(hospital_spending,mean=mean(Avg.Spending.Per.Episode..Nation.),
                            maximum=max(Avg.Spending.Per.Episode..Nation.),
                            minimum=min(Avg.Spending.Per.Episode..Nation.),
                            median=median(Avg.Spending.Per.Episode..Nation.))
mean     maximum   minimum  median
1820.409  20025       0      109

hospital_spending_DT[,.(mean=mean(Avg.Spending.Per.Episode..Nation.),
                        maximum=max(Avg.Spending.Per.Episode..Nation.),
                        minimum=min(Avg.Spending.Per.Episode..Nation.),
                        median=median(Avg.Spending.Per.Episode..Nation.))]
mean      maximum   minimum  median
1820.409  20025       0      109

当然,我们也可以对各分组的数据块分别求概述性统计量。在dplyr中使用group_by()函数,data.table中指定by参数即可:

head(hospital_spending_DT[,.(mean=mean(Avg.Spending.Per.Episode..Hospital.)),by=.(Hospital)])
mygroup= group_by(hospital_spending,Hospital,State)
from_dplyr = summarize(mygroup,mean=mean(Avg.Spending.Per.Episode..Hospital.))

from_data_table=hospital_spending_DT[,.(mean=mean(Avg.Spending.Per.Episode..Hospital.)), by=.(Hospital,State)]

compare(from_dplyr,from_data_table, allowAll=TRUE)

链式操作

在dplyr和data.table包中,我们可以使用链式操作来实现代码的连续性。在dplyr中,使用magrittr包中的%>%管道函数非常酷。%>%的功能是用于实现将一个函数的输出传递给下一个函数的第一个参数。在data.table中,我们可以使用%>%或[来实现链式操作。

from_dplyr=hospital_spending %>% group_by(Hospital,State) %>% summarize(mean=mean(Avg.Spending.Per.Episode..Hospital.))

from_data_table=hospital_spending_DT[,.(mean=mean(Avg.Spending.Per.Episode..Hospital.)), by=.(Hospital,State)]

compare(from_dplyr,from_data_table, allowAll=TRUE)

hospital_spending %>% group_by(State) %>% summarize(mean=mean(Avg.Spending.Per.Episode..Hospital.)) %>% 
arrange(desc(mean)) %>% head(10) %>% 
        mutate(State = factor(State,levels = State[order(mean,decreasing =TRUE)])) %>% 
          ggplot(aes(x=State,y=mean))+geom_bar(stat='identity',color='darkred',fill='skyblue')+
          xlab("")+ggtitle('Average Spending Per Episode by State')+
          ylab('Average')+ coord_cartesian(ylim = c(3800, 4000))
hospital_spending_DT[,.(mean=mean(Avg.Spending.Per.Episode..Hospital.)),
                                     by=.(State)][order(-mean)][1:10] %>% 
            mutate(State = factor(State,levels = State[order(mean,decreasing =TRUE)])) %>% 
           ggplot(aes(x=State,y=mean))+geom_bar(stat='identity',color='darkred',fill='skyblue')+
          xlab("")+ggtitle('Average Spending Per Episode by State')+
          ylab('Average')+ coord_cartesian(ylim = c(3800, 4000))
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容