由菜鳥到進行簡單的數據分析是怎樣的一種體驗
任務一:處理某醫院2016年銷售數據
任務二:畫出每周消費曲線圖
任務三:進行簡單的業務數據分析
任務分解:
先安2個包。這是R的特色,裡邊有各式各樣的包,每個包里有不同的函數來處理數據結構,就跟玩CS裡邊的裝備包一樣,不同的包里有不同的武器。
> install.packages("openxlsx")n> library("openxlsx")n> install.packages("stringr")n> library(stringr)n> readFilePath <- "f:/大數據/朝陽醫院2016年銷售數據.xlsx"n> excelData <- read.xlsx(readFilePath,"Sheet1")n> excelData n
注意,這裡邊「Sheet」的首字母要大寫,否則報錯
運行結果: 數據量太大,這只是部分截圖《R語言實戰》的作者Robert I. Kabacoff在書中說:「數據是一件麻煩事——一件非常非常 麻煩的事。在我的工作中,有多達60%的數據分析時間都花在了實際分析前數據的準備上。」足以說明數據的預處理在數據分析中的重要性和複雜性。我的理解就是將它比喻成做菜前的準備工作,包括洗菜,理菜,切菜等。可能不太恰當,不過便於理解。
第一步:列名重命名
將列表的中文名稱重命名成英文名稱,便於使用函數運算
> names(excelData) <- c("time","cardID", "drugID","drugName","saleNum","virtualmoney","actualmoney")n
第二步:刪除缺失數據
Excel表格中的某些數據存在缺失不全的情況,實際的處理過程中要將這些缺失的數據刪除才能便於後期處理。可以先使用is.na()對數據框中判斷銷售數據框中哪些是缺失值(NA),然後用邏輯非(!X)來挑選出非缺失值,也就是有用數據。
> excelData <- excelData[!is.na(excelData$time),]n
注意:方括弧中的逗號表示對數據框的行進行操作,逗號左邊是行,不能省略。
第三步:處理日期
在《R語言實戰》中的4.6節講到「日期值通常以字元串的形式輸入到R中,然後轉化為以數值形式存儲的日期變數」,在截圖中可以看到列表中的日期(time)是「2016-01-01 星期五」,而實際上我們並不需要「星期五」這個數據,所以要把這行字元串拆分成「2016-01-01」,「星期五」兩行,並返回成矩陣格式。
教程中用到了字元串分割函數 str_split_fixed(),在《R語言實戰》當中並沒有給出這是函數怎麼用的,只好谷歌,終於搞清楚了這個函數是幹嘛用的。這裡我參照了Learn R專欄文章裡邊的講解@Jason 。更多關於stringr包的字元串處理函數可以參照這裡:stringr包的字元串處理函數合集> timeSplit <- str_split_fixed(excelData$time, " ",2)n> excelData$time <-timeSplit[,1]n
運行結果:
將日期的字元串類型轉換成數值型的格式,採用as.Date()函數
> excelData$time <- as.Date(excelData$time, "%Y-%m-%d")n
運行結果:
第四步:數據類型轉換
將列表中的銷售金額,應收金額,實收金額轉換為數值型變數.由於列表中的各項金額是字元型變數,無法進行後續的排序操作,所以要先將以上變數轉為數值型變數,這裡用到as.numeric()函數
> excelData$saleNumber <- as.numeric(excelData$saleNumber)n> excelData$virtualmoney <- as.numeric(excelData$virtualmoney)n> excelData$actualmoney <- as.numeric(excelData$actualmoney)n
第五步:數據排序
將銷售時間對數據進行升序排序
> excelData <- excelData[order(excelData$time, decreasing = FALSE),]n
到這裡數據預處理結束(洗完菜了,接下來炒菜)
- 計算患者月均消費次數
- 計算患者月均消費金額
- 計算客單價
- 數據可視化(將分析指標用圖表呈現出來)
第一步:月均消費次數
- 患者月均消費次數 = 總消費次數 / 總月份數
- 總消費次數 = 列表總行數
- 總月份數 = 總天數 / 30(天/月)
- 總天數 = 行尾時間 - 行首時間
kpi1 <- excelData[!duplicated(excelData[,c("time","cardno")] ),]n
因為統計的是月平均消費次數,所以同一個人同一天多次購買只算做一次,將將重複的時間和社保卡號刪除,保留在kpi1數組中。總消費次數就是列表中的行數,所以用nrow()函數統計行數就行了。
consumeNumber <- nrow(kpi1) #總消費次數nendTime <- kpi1$time[nrow(kpi1)] #行尾時間nstartTime <- kpi1$time[1] #行首時間nday <- as.numeric(endTime -startTime) #總天數 = 行尾時間 - 行首時間nmonth <- day %/% 30 #總月份數nmonthConsume <- consumeNumber / month #月均消費次數nmonthConsume <- format(round(monthConsume, 2), nsmall = 2) #輸出指定格式(保留2位小數的數值)n
輸出結果:
關於format()函數在Stack Overflow網站上找到了註解第二步:月均消費金額
totalMoney <- sum(excelData$actualmoney,na.rm=TRUE) #總金額nnmonthMoney <- totalMoney / month #月均消費金額n
註:代碼中的na.rm()函數是處理列表中的缺失值,在《R語言實戰》中的「4.5.2 在分析中排除缺失值 」中有詳細介紹,見下圖:
第三步:計算客單價
pct <- totalMoney / consumeNumber #客單價nnpct <- format(round(pct, 2), nsmall = 2) #結果保留2位小數n
第四步:分析消費趨勢
思路:
- 列出每周消費金額
- 計算出共有多少周
- 列出 周數
要求以每周顧客的消費金額來分析消費趨勢,需要用到tapply()函數進行分類
tapply(x,f,g) x為向量,f為因子列,g為操作函數,即x向量根據f的條件來進行g函數的運算。
week <- tapply(excelData$actualmoney, format(excelData$time, "%Y-%U"), sum) #將列表中實際消費金額以「年份- 第幾周」的形式算出周消費金額 "%Y-%U"表示:年份-第幾周n
運行結果
tapply的結果是一個二維數組,如果要進行繪圖的話需要將數組轉化為數據框
week <- as.data.frame.table(week)n
運行結果:
在結果中看到了表頭出現了「Var1」和「Freq」兩組默認的列名。因此需要將列名重命名names(week) <- c("time","actualmoney")n
這裡要在列表後添加一個周數統計欄,所以先將(年份-第幾周)這一欄轉為字元串類型,並用nrow()計算行數,最後以向量形式賦值給周數統計表
week$time <- as.character(week$time)nweek$timeNumber <- c(1:nrow(week))n
最後的week數據框是這樣的
好了,終於到了激動人心的數據可視化階段,先來調整圖表參數plot(week$timeNumber, week$actualmoney,n xlab="時間(年份-第幾周)",n ylab="消費金額", n xaxt = "n", #禁用x軸刻度n main= "2016年朝陽醫院消費曲線", n col="blue",n type="b")naxis(1,at=week$timeNumber, labels=week$time, cex.axis = 1.5) #設置x軸坐標軸n
運行結果:
大功告成,完成了一個簡單的數據分析,花費了將近1周的時間,有幾點感悟- 按照給定的源代碼敲上去運行出來並不難,關鍵是要弄懂為什麼要敲這行代碼,也就是最核心的分析思維是什麼?實現的過程是什麼?每個調用的函數功能是什麼?
- 看代碼也需要隻字不差,不懂得要一個個搞懂,回過去看《R語言實戰》的內容,沒有的翻牆用Google搜索,嘗試著把每一行代碼弄清楚。
- 要有足夠的耐心,剛開始慢,往後就快了,代碼敲上去明明一樣,為什麼運行錯誤?回去一遍遍試了才知道,也許是中英文半形符號、大小寫、用戶名文件是中文,沒有將每一步結果輸出等等。各種坑,踩一遍,改過來下次不再犯,然後錯誤越來越少。
推薦閱讀:
※仿經濟學人——矩陣氣泡圖
※打開股票量化的黑箱(自己動手寫一個印鈔機) 第六章
※c/c++ 有哪些數據可視化類庫?
※Power BI應用場景賞析-銷售篇
※Excel繪製多種風格「條形圖」