小白學(xué)R—復(fù)雜數(shù)據(jù)處理

這一關(guān)屬于進(jìn)階關(guān)脂男,難度相比前面提高了不少宰翅,所以花費(fèi)的時(shí)間也多了一些。
本關(guān)的學(xué)習(xí)內(nèi)容主要為:如何編寫(xiě)函數(shù);數(shù)據(jù)處理:dplyr, ggplot2耸彪;如何編寫(xiě)業(yè)務(wù)模塊蝉娜;代碼如何調(diào)試。

1.如何編寫(xiě)函數(shù)

1.1 自編函數(shù)模板

my_fun <- function(arg1,arg2,...){
  body
  ruturn(data)
  }

例如下面荧呐,若add(1,2)概疆,結(jié)果z=3

add <- function(x,y) {
  z <- x+y
  return(z)
}

1.2 控制語(yǔ)句-循環(huán)和條件

1.2.1 for 循環(huán)的基本模板

for(i in data){
  body
}

假設(shè)有一項(xiàng)重復(fù)性工作,如下:

library(stringr)
print(str_c("第幾次吃飯",1,sep=":"))
print(str_c("第幾次吃飯",2,sep=":"))
print(str_c("第幾次吃飯",3,sep=":"))

重復(fù)去寫(xiě)1,2,3,...會(huì)很麻煩楣颠,我們可以用for循環(huán)來(lái)簡(jiǎn)化:

for(i in 1:3) {
  print(
  str_c("第幾次吃飯",i,sep=":")
  )
  }

1.2.2 while循環(huán)的基本模板

while (condition){
  body
}

例如:

i <- 10
while(i>0){
  print(
    i <- i-1)
  }

注意:while 一定要有循環(huán)結(jié)束的判斷條件,否則會(huì)無(wú)限循環(huán)下去。

1.2.3 條件語(yǔ)句的基本模板

if(condition){
  body
}else{
  body
}

例如錢(qián)包內(nèi)有100侧馅,吃飯花費(fèi)30,余額提醒:

money <- 100
if(money>0){
  money <- money-30
  print("錢(qián)包還有錢(qián),不需要取錢(qián)")
}else{
  print("錢(qián)包沒(méi)有錢(qián),去取款機(jī)吧")
}

再舉一個(gè)復(fù)雜點(diǎn)的例子:飯卡余額1000酬屉,每天吃3頓飯,每頓5元垛吗,余額低于5元蔚舀,提示:

everday <- function(eatNumber,money){
  for(i in eatNumber){
    eatNumber <- str_c("今天吃第幾次飯:",i,sep="")
    money <- money-5*i
    print(money)
    print(eatNumber)
  }
  if(money<5){
    print("飯卡沒(méi)錢(qián)了:去銀行取錢(qián)")
  }else{
      print("飯卡還有錢(qián):不用去銀行")
    }
}

2.數(shù)據(jù)處理-dplyr、ggplot2

dplyr是一套數(shù)據(jù)處理工具礼患,它提供了多個(gè)函數(shù)來(lái)幫助你完成常見(jiàn)的數(shù)據(jù)處理工作:

  • mutate()函數(shù)對(duì)已有列進(jìn)行數(shù)據(jù)運(yùn)算并添加為新列,類(lèi)似transform()
  • select()根據(jù)列名選擇出需要的子集
  • filter()基于數(shù)值挑選對(duì)象,可以按給定的邏輯條件篩選符合要求的子數(shù)據(jù)集
  • summarise()對(duì)數(shù)據(jù)框調(diào)用函數(shù)進(jìn)行匯總操作, 返回一維的結(jié)果
  • arrange()按給定的列名依次對(duì)行進(jìn)行排序领曼,默認(rèn)為升序,類(lèi)似order()
    ggplot2是R中重要的繪圖工具:
  • ggplot2的核心理念是將繪圖與數(shù)據(jù)分離,數(shù)據(jù)相關(guān)的繪圖與數(shù)據(jù)無(wú)關(guān)的繪圖分離
  • ggplot2是按圖層作圖
  • ggplot2保有命令式作圖的調(diào)整函數(shù)幻碱,使其更具靈活性
  • ggplot2將常見(jiàn)的統(tǒng)計(jì)變換融入到了繪圖中喇聊。
    接下來(lái)誓篱,我們利用一個(gè)例子,來(lái)深入學(xué)習(xí)這兩個(gè)包。

2.1 數(shù)據(jù)分析流程

數(shù)據(jù)預(yù)分析步驟:理解數(shù)據(jù)-數(shù)據(jù)導(dǎo)入-數(shù)據(jù)預(yù)處理-數(shù)據(jù)計(jì)算-數(shù)據(jù)顯示赎线。

2.1.1 數(shù)據(jù)導(dǎo)入

首先加載包和數(shù)據(jù)集。

install.packages("dplyr")
install.packages("nycflights13")
library(dplyr)
library(nycflights13)

2.1.2 數(shù)據(jù)預(yù)處理步驟

進(jìn)行數(shù)據(jù)預(yù)處理的步驟:選擇子集-列重命名-刪除缺失數(shù)據(jù)-處理日期-類(lèi)型轉(zhuǎn)換-數(shù)據(jù)排序。

2.1.2.1 選擇子集

確定分析目標(biāo):航班航線(xiàn)距離與延誤時(shí)間的關(guān)系

# 查看數(shù)據(jù)結(jié)構(gòu)
str(flights)
myFlights <- select(flights,year,month,day,
                    dep_delay,arr_delay,distance,dest)
# select也可以進(jìn)行模糊匹配
select(data,
       starts_with("abc"),    #以abc開(kāi)頭
       ends_with("xyz"),      #以xyz結(jié)尾
       contains("ijk"),       #包含ijk
       matches("(.)\\1"))     #正則表達(dá)式,字符或數(shù)據(jù)匹配

2.1.2.2 列名重命名

myFlights <- rename(myFlights,destination=dest)  
#tips:新列名在前竞惋,舊列名在后

2.1.2.3 刪除缺失數(shù)據(jù)

myFlights <- filter(myFlights,!is.na(dep_delay),!is.na(arr_delay))

filter()更多用法:

# 查找數(shù)據(jù)
filter(myFlights,month==12,day==25)  #查找12.25的航班
filter(myFlights,arr_delay>120|dep_delay>120)  #延誤超2h的航班

2.1.2.4 數(shù)據(jù)排序

這里我們用的是dplyr中的arrange()函數(shù)嗓奢,默認(rèn)為升序钳幅,desc()讓表示降序诬乞。

arrange(myFlights,dep_delay)
arrange(myFlights,desc(dep_delay))

2.1.3 數(shù)據(jù)計(jì)算

用dplyr包的分組函數(shù)group_by()和組合函數(shù)summarise()來(lái)進(jìn)行計(jì)算票堵。
數(shù)據(jù)處理的一般模式: Split(數(shù)據(jù)分組) - Apply(應(yīng)用函數(shù)) - Combine(組合結(jié)果)

# 按照目的地進(jìn)行分組
by_dest <- group_by(myFlights,destination)
# 求平均到達(dá)延誤時(shí)間和平均航行里程
 delay <- summarise(by_dest,
                    count=n(), #航班數(shù)-每個(gè)分組有多少數(shù)據(jù)
                    dist=mean(distance,na.rm = TRUE),
                    delay=mean(arr_delay,na.rm=TRUE)) 
 # 移除噪音數(shù)據(jù)--移除樣本數(shù)量較小的數(shù)據(jù)
 delay <- filter(delay,count>20)
 以上的過(guò)程,可以利用管道:%>% 進(jìn)行簡(jiǎn)化
 delays <- flights%>%
   group_by(dest)%>%
   summarise(
     count=n(),
     dist=mean(distance,na.rm = TRUE),
     delay=mean(arr_delay,na.rm = TRUE)
   )%>%
   filter(count>20)

2.1.4 數(shù)據(jù)顯示

數(shù)據(jù)顯示要用到繪圖包ggplot2瞳浦,ggplot()是一個(gè)圖層一個(gè)圖層來(lái)繪制圖形的担映,用其中的加號(hào)"+"來(lái)結(jié)合各個(gè)圖層,ggplot2繪圖的一般模板為:

# ggplot(data = <DATA> ) +  #創(chuàng)建畫(huà)板
#   <GEOM_FUNCTION>(mapping=aes( <MAPPINGS>))  #添加圖層

應(yīng)用到本實(shí)例中叫潦,ggplot()括號(hào)內(nèi)的參數(shù)是要使用的數(shù)據(jù)蝇完,然后是geom_point(mapping = aes(x = dist, y = delay)),這是用來(lái)繪制散點(diǎn)圖的矗蕊,x軸為距離dist短蜕,y軸為延遲時(shí)間delay。 geom_smooth(mapping = aes(x = dist, y = delay))用來(lái)給圖加入平滑的曲線(xiàn)傻咖,以展示x和y的關(guān)系朋魔。

ggplot(data=delay)+
  geom_point(mapping = aes(x=dist,y=delay))+
  geom_smooth(mapping = aes(x=dist,y=delay))

3.如何編寫(xiě)業(yè)務(wù)模塊

3.1 模塊介紹

一個(gè)項(xiàng)目通常會(huì)有以下幾個(gè)模塊:

  • 視圖模塊(view):數(shù)據(jù)顯示的實(shí)現(xiàn)代碼
  • 業(yè)務(wù)邏輯模塊(service):數(shù)據(jù)處理的代碼
  • 數(shù)據(jù)層模塊(db):數(shù)據(jù)分析要連接的數(shù)據(jù)庫(kù)
    各個(gè)模塊的文件會(huì)放在相同名字的文件夾里面,根據(jù)需要還可以創(chuàng)建其他模塊:
  • 公共模塊(util):放項(xiàng)目的公共材料卿操,比如項(xiàng)目的配置信息
  • 公共數(shù)據(jù)(data):數(shù)據(jù)分析用到的數(shù)據(jù)
  • 日志模塊(log):數(shù)據(jù)處理流程
  • 數(shù)據(jù)輸出模塊(output):放數(shù)據(jù)分析的結(jié)果警检,比如繪制的圖形和Excel文件等
    例如本例中,util里的packageManager.R代碼:
#管理安裝包
# 數(shù)據(jù)包
packages <- c("nycflights13")
if (length(setdiff(packages, rownames(installed.packages()))) > 0) {
install.packages(setdiff(packages, rownames(installed.packages()))) 
}
#字符串包
packages <- c("stringr")
if (length(setdiff(packages, rownames(installed.packages()))) > 0) {
install.packages(setdiff(packages, rownames(installed.packages()))) 
}
#圖形包
packages <- c("ggplot2")
if (length(setdiff(packages, rownames(installed.packages()))) > 0) {
install.packages(setdiff(packages, rownames(installed.packages()))) 
}
#數(shù)據(jù)處理包
packages <- c("dplyr")
if (length(setdiff(packages, rownames(installed.packages()))) > 0) {
install.packages(setdiff(packages, rownames(installed.packages()))) 
}

3.2 業(yè)務(wù)邏輯模塊

在業(yè)務(wù)邏輯模塊的文件夾(service)里創(chuàng)建R腳本flight.R:

install.packages("dplyr") 
install.packages("nycflights13") 
library(dplyr)
library(nycflights13)# for data
#航班航行距離與延誤時(shí)間的關(guān)系
#輸入:不需要輸入?yún)?shù)
#輸出:返回每個(gè)目的地的平均航行距離害淤,平均延誤時(shí)間
disDelay <- function(){
#選擇子集
myFlights <- select(flights,
                    year,month,day,
                    dep_delay,arr_delay,
                    distance,dest)
#列名重命名扇雕,等號(hào)左邊是新列名,右邊是就列名
myFlights <- rename(myFlights, destination = dest)
#刪除缺失數(shù)據(jù)窥摄,這里的空值NA代表航班取消
myFlights <- filter(myFlights, 
!is.na(dep_delay), 
!is.na(arr_delay))
#數(shù)據(jù)排序
myFlights <- arrange(myFlights, desc(dep_delay))
#數(shù)據(jù)計(jì)算:航班航行距離與延誤時(shí)間的關(guān)系    
delay <- myFlights %>% 
  group_by(destination) %>% 
  summarise(
    count = n(),
    dist = mean(distance, na.rm = TRUE),
    delay = mean(arr_delay, na.rm = TRUE)
) %>% 
  filter(count > 20)
return(delay)
}

3.3 視圖模塊

在視圖模塊文件夾(view)里把前面的數(shù)據(jù)顯示實(shí)現(xiàn)代碼(flightView.R)存入:

library(ggplot2) 
library(stringr)
#獲取當(dāng)前項(xiàng)目運(yùn)行根路徑
projectPath <- getwd()
#獲取service路徑
servicePath <- str_c(projectPath,
                   "service",
                   "flight.R",
                   sep="/")
#編譯R文件镶奉,利用source()調(diào)用外部代碼并運(yùn)行
source(servicePath)
#業(yè)務(wù)邏輯:航班航行距離與延誤時(shí)間的關(guān)系
delay <- disDelay()
#繪制散點(diǎn)圖
view <- ggplot(data = delay) + 
geom_point(mapping = aes(x = dist, y = delay)) +
geom_smooth(mapping = aes(x = dist, y = delay))
#定義散點(diǎn)圖保存路徑
outputpath <- str_c(projectPath,"output","delayFlight.jpg",sep="/")
#利用ggsave()來(lái)保存散點(diǎn)圖到上面的路徑中
ggsave(filename=outputpath, plot=view) 

4.代碼如何調(diào)試

Rstudio中的代碼搜索功能,例如想知道業(yè)務(wù)邏輯模塊中的disDelay 具體代碼崭放,可以雙擊選中函數(shù)-進(jìn)入函數(shù)定義的地方:Rstudio-Code-Go to Function Definition哨苛。
一個(gè)簡(jiǎn)單的代碼調(diào)試過(guò)程:
代碼出現(xiàn)錯(cuò)誤-錯(cuò)誤在哪塊代碼-理解錯(cuò)誤代碼大概什么意思-打斷點(diǎn)(stop)-編譯(source)-重新執(zhí)行代碼-找到錯(cuò)誤原因。
寫(xiě)的比較簡(jiǎn)單币砂,大家可以找一些參考資料學(xué)習(xí)建峭。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市决摧,隨后出現(xiàn)的幾起案子迹缀,更是在濱河造成了極大的恐慌,老刑警劉巖蜜徽,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異票摇,居然都是意外死亡拘鞋,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)矢门,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)盆色,“玉大人灰蛙,你說(shuō)我怎么就攤上這事「舳悖” “怎么了摩梧?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)宣旱。 經(jīng)常有香客問(wèn)我仅父,道長(zhǎng),這世上最難降的妖魔是什么浑吟? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任笙纤,我火速辦了婚禮,結(jié)果婚禮上组力,老公的妹妹穿的比我還像新娘省容。我一直安慰自己,他們只是感情好燎字,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布腥椒。 她就那樣靜靜地躺著,像睡著了一般候衍。 火紅的嫁衣襯著肌膚如雪笼蛛。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天脱柱,我揣著相機(jī)與錄音伐弹,去河邊找鬼。 笑死榨为,一個(gè)胖子當(dāng)著我的面吹牛惨好,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播随闺,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼日川,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了矩乐?” 一聲冷哼從身側(cè)響起龄句,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎散罕,沒(méi)想到半個(gè)月后分歇,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡欧漱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年职抡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片误甚。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缚甩,死狀恐怖谱净,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情擅威,我是刑警寧澤壕探,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站郊丛,受9級(jí)特大地震影響李请,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜宾袜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一捻艳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧庆猫,春花似錦认轨、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至杉畜,卻和暖如春纪蜒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背此叠。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工纯续, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人灭袁。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓猬错,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親茸歧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子倦炒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 第二章 使用ArcPy編寫(xiě)腳本 ||| 第四章 查找和修復(fù)數(shù)據(jù)源 我們將在本章介紹以下案例: 引用當(dāng)前地圖文檔 引...
    muyan閱讀 14,465評(píng)論 19 23
  • 復(fù)雜數(shù)據(jù)分析處理的一般過(guò)程為:理解數(shù)據(jù)——>數(shù)據(jù)導(dǎo)入——>數(shù)據(jù)預(yù)處理——>數(shù)據(jù)計(jì)算——>數(shù)據(jù)顯示其中,數(shù)據(jù)的預(yù)處理...
    Mr_dvbkhm閱讀 648評(píng)論 0 0
  • 初冬软瞎,一場(chǎng)大風(fēng)把人一下拉進(jìn)了冬天逢唤。周末,去了趟武漢涤浇,來(lái)也匆匆去也匆匆鳖藕。 考完還有半天時(shí)間,誤打誤撞到了關(guān)谷廣場(chǎng)只锭,大...
    小小娃兒媽閱讀 269評(píng)論 2 6
  • 雨水. 茶湯 常江 捧著手中的六月 掌心的紫砂內(nèi)斂著光芒 一縷縷舊光陰 ...
    藝術(shù)與評(píng)論閱讀 244評(píng)論 0 7
  • 看完了大型民族舞劇《王羲之》吊奢,內(nèi)心的受到了無(wú)比的震撼。或許因?yàn)檫@是第一次的觀(guān)看舞劇页滚,在無(wú)知的基礎(chǔ)上才特別的興奮...
    思匆閱讀 441評(píng)論 13 10