一個之前未解決的遺留問題
之前實習的時候偶然間被詢問了一個數據結構變形的問題,但是是在excel裏,所以不太會,最近學R,發現R解決起來還挺方便,整理了一下放在這裏,以便日後需要再來查閱。
工具:R, tapply, tidyr - spread, sqldf - sqldf
問題描述:
如果有這樣的一個數據集
要如何把它變成這種結構:
a1 | b1 | c1 | d1 | |
---|---|---|---|---|
A | 對應sum(GMV) | 對應sum(GMV) | 對應sum(GMV) | 對應sum(GMV) |
B | 對應sum(GMV) | 對應sum(GMV) | 對應sum(GMV) | 對應sum(GMV) |
C | 對應sum(GMV) | 對應sum(GMV) | 對應sum(GMV) | 對應sum(GMV) |
D | 對應sum(GMV) | 對應sum(GMV) | 對應sum(GMV) | 對應sum(GMV) |
構建數據集
Region <- c('A','B','A','B','C','E','D','C','A','E','D','B')
GMV <- c(200,345,432,345,234,554,234,455,542,252,234,264)
Type <- rep(c('a1','b1','c1','d1'),3)
dat <- data.frame(Region,GMV,Type)
得到上述數據集。
方法1 tapply
用R自帶的tapply函數,對數據dat進行變形:把字段Type下的變量拓展爲新的字段,用sum(GMV)填充,如果沒有對應的填充值就顯示缺失。
把結果轉化爲dataframe便於轉存爲csv等格式。
a = as.data.frame( tapply(dat$GMV,dat[,c('Region','Type')],sum) )
write.table(a, file = 'C:/Users/rapha/Desktop/Reading/expdat.csv', sep = ',')
結果:
方法的優點是方便,缺點是隻能處理這樣三個字段的數據集。
方法2 tidyr-spread + sqldf
install.packages('tidyr')
library(tidyr)
安裝一下。
關於spread用法:
spread(data, key, value, fill = NA, convert = FALSE, drop = TRUE)
data:爲需要轉換的表
key:需要將變量值拓展爲字段的變量
value:需要分散的值(用於填充)
fill:對於缺失值,可將fill的值賦值給被轉型後的缺失值
(https://blog.csdn.net/pilouduo1367/article/details/69675678#22-長轉寬-spread)
但是!在使用spread之前,首先要對value值group by一下,不然不能使用這個函數…。
比如在原先的數據中:
第1行和第9行的(Region,Type)是一樣的,應當加總起來。
所以首先要進行一下group by 的操作。這裏我是直接使用了一下sqldf的包進行了操作。
install.packages('sqldf')
library(sqldf)
new_dat <- sqldf('select Region, sum(GMV) as GMV, Type from dat group by Region, Type')
spread(new_dat,Type,GMV)
結果:
方法的優點是比較規範,在有多個字段的時候也可以很好的處理。缺點是步驟多。