我們會(huì)根據(jù)業(yè)務(wù)的要求做各種復(fù)雜的報(bào)表,包括了分組师骗、排序历等、過(guò)濾、轉(zhuǎn)置辟癌、差分寒屯、填充、移動(dòng)、合并寡夹、分裂处面、分布、去重菩掏、找重魂角、填充 等等的操作。
有時(shí)為了計(jì)算一個(gè)業(yè)務(wù)指標(biāo)智绸,你的SQL怎么寫都不會(huì)少于10行時(shí)野揪,另外你可能也會(huì)抱怨Excel功能不夠強(qiáng)大,這個(gè)時(shí)候R語(yǔ)言絕對(duì)是不二的選擇了瞧栗。用R語(yǔ)言可以高效地斯稳、優(yōu)雅地解決數(shù)據(jù)處理的問(wèn)題,讓R來(lái)幫你打開(kāi)面向數(shù)據(jù)的思維模式迹恐。
目錄
為什么要用R語(yǔ)言做數(shù)據(jù)處理平挑?
數(shù)據(jù)處理基礎(chǔ)
個(gè)性化的數(shù)據(jù)變換需求
我們要先了解一下R語(yǔ)言支持的數(shù)據(jù)類型,以及這些常用類型的特點(diǎn)系草。對(duì)于BI的數(shù)據(jù)處理的工作來(lái)說(shuō),可能有4種類型是最常用的唆涝,分別是向量找都、矩陣、數(shù)據(jù)框廊酣、時(shí)間序列能耻。
向量 Vector : c()
矩陣 Matrix: matrix()
數(shù)據(jù)框 DataFrame: data.frame()
時(shí)間序列 XTS: xts()
我主要是用R語(yǔ)言來(lái)做量化投資,很多的時(shí)候亡驰,都是和時(shí)間序列類型數(shù)據(jù)打交道晓猛,所以我把時(shí)間序列,也定義為R語(yǔ)言最常用的數(shù)據(jù)處理的類型凡辱。時(shí)間序列類型戒职,使用的是第三方包xts中定義的類型。
2. 數(shù)據(jù)處理基礎(chǔ)
2.1 創(chuàng)建一個(gè)數(shù)據(jù)集
創(chuàng)建一個(gè)向量數(shù)據(jù)集透乾。
> x<-1:20;x
[1]? 1? 2? 3? 4? 5? 6? 7? 8? 9 10 11 12 13 14 15 16 17 18 19 20
創(chuàng)建一個(gè)矩陣數(shù)據(jù)集洪燥。
> m<-matrix(1:40,ncol=5);m
? ? [,1] [,2] [,3] [,4] [,5]
[1,]? ? 1? ? 9? 17? 25? 33
[2,]? ? 2? 10? 18? 26? 34
[3,]? ? 3? 11? 19? 27? 35
[4,]? ? 4? 12? 20? 28? 36
[5,]? ? 5? 13? 21? 29? 37
[6,]? ? 6? 14? 22? 30? 38
[7,]? ? 7? 15? 23? 31? 39
[8,]? ? 8? 16? 24? 32? 40
創(chuàng)建一個(gè)數(shù)據(jù)框數(shù)據(jù)集
> df<-data.frame(a=1:5,b=c('A','A','B','B','A'),c=rnorm(5));df
? a b? ? ? ? ? c
1 1 A? 1.1519118
2 2 A? 0.9921604
3 3 B -0.4295131
4 4 B? 1.2383041
5 5 A -0.2793463
創(chuàng)建一個(gè)時(shí)間序列數(shù)據(jù)集,時(shí)間序列使用的第三方的xts類型乳乌。關(guān)于xts類型的詳細(xì)介紹捧韵,請(qǐng)參考文章 可擴(kuò)展的時(shí)間序列xts。
> library(xts)
> xts(1:10,order.by=as.Date('2017-01-01')+1:10)
? ? ? ? ? [,1]
2017-01-02? ? 1
2017-01-03? ? 2
2017-01-04? ? 3
2017-01-05? ? 4
2017-01-06? ? 5
2017-01-07? ? 6
2017-01-08? ? 7
2017-01-09? ? 8
2017-01-10? ? 9
2017-01-11? 10
2.2 查看數(shù)據(jù)概況
通常進(jìn)行數(shù)據(jù)分析的第一步是汉操,查看一下數(shù)據(jù)的概況信息再来,在R語(yǔ)言里可以使用summary()函數(shù)來(lái)完成。
# 查看矩陣數(shù)據(jù)集的概況
> m<-matrix(1:40,ncol=5)
> summary(m)
? ? ? V1? ? ? ? ? ? V2? ? ? ? ? ? ? V3? ? ? ? ? ? ? V4? ? ? ? ? ? ? V5? ? ?
Min.? :1.00? Min.? : 9.00? Min.? :17.00? Min.? :25.00? Min.? :33.00?
1st Qu.:2.75? 1st Qu.:10.75? 1st Qu.:18.75? 1st Qu.:26.75? 1st Qu.:34.75?
Median :4.50? Median :12.50? Median :20.50? Median :28.50? Median :36.50?
Mean? :4.50? Mean? :12.50? Mean? :20.50? Mean? :28.50? Mean? :36.50?
3rd Qu.:6.25? 3rd Qu.:14.25? 3rd Qu.:22.25? 3rd Qu.:30.25? 3rd Qu.:38.25?
Max.? :8.00? Max.? :16.00? Max.? :24.00? Max.? :32.00? Max.? :40.00?
# 查看數(shù)據(jù)框數(shù)據(jù)集的概況信息
> df<-data.frame(a=1:5,b=c('A','A','B','B','A'),c=rnorm(5))
> summary(df)
? ? ? a? ? b? ? ? ? ? c? ? ? ? ?
Min.? :1? A:3? Min.? :-1.5638?
1st Qu.:2? B:2? 1st Qu.:-1.0656?
Median :3? ? ? ? Median :-0.2273?
Mean? :3? ? ? ? Mean? :-0.1736?
3rd Qu.:4? ? ? ? 3rd Qu.: 0.8320?
Max.? :5? ? ? ? Max.? : 1.1565?
通過(guò)查看概況磷瘤,可以幫助我們簡(jiǎn)單了解數(shù)據(jù)的一些統(tǒng)計(jì)特征芒篷。
2.3 數(shù)據(jù)合并
我們經(jīng)常需要對(duì)于數(shù)據(jù)集搜变,進(jìn)行合并操作,讓數(shù)據(jù)集滿足處理的需求梭伐。對(duì)于不同類型的數(shù)據(jù)集痹雅,有不同的處理方法。
向量類型
> x<-1:5
> y<-11:15
> c(x,y)
[1]? 1? 2? 3? 4? 5 11 12 13 14 15
數(shù)據(jù)框類型的合并操作糊识。
> df<-data.frame(a=1:5,b=c('A','A','B','B','A'),c=rnorm(5));df
? a b? ? ? ? ? c
1 1 A? 1.1519118
2 2 A? 0.9921604
3 3 B -0.4295131
4 4 B? 1.2383041
5 5 A -0.2793463
# 合并新行
> rbind(df,c(11,'A',222))
? a b? ? ? ? ? ? ? ? ? c
1? 1 A? ? 1.1519117540872
2? 2 A? 0.992160365445798
3? 3 B -0.429513109491881
4? 4 B? 1.23830410085338
5? 5 A -0.279346281854269
6 11 A? ? ? ? ? ? ? ? 222
# 合并新列
> cbind(df,x=LETTERS[1:5])
? a b? ? ? ? ? c x
1 1 A? 1.1519118 A
2 2 A? 0.9921604 B
3 3 B -0.4295131 C
4 4 B? 1.2383041 D
5 5 A -0.2793463 E
# 合并新列
> merge(df,LETTERS[3:5])
? a b? ? ? ? ? c y
1? 1 A? 1.1519118 C
2? 2 A? 0.9921604 C
3? 3 B -0.4295131 C
4? 4 B? 1.2383041 C
5? 5 A -0.2793463 C
6? 1 A? 1.1519118 D
7? 2 A? 0.9921604 D
8? 3 B -0.4295131 D
9? 4 B? 1.2383041 D
10 5 A -0.2793463 D
11 1 A? 1.1519118 E
12 2 A? 0.9921604 E
13 3 B -0.4295131 E
14 4 B? 1.2383041 E
15 5 A -0.2793463 E
2.4 累計(jì)計(jì)算
累計(jì)計(jì)算绩社,是很常用的一種計(jì)算方法,就是把每個(gè)數(shù)值型的數(shù)據(jù)赂苗,累計(jì)求和或累計(jì)求積愉耙,從而反應(yīng)數(shù)據(jù)的增長(zhǎng)的一種特征。
向量x
> x<-1:10;x
[1]? 1? 2? 3? 4? 5? 6? 7? 8? 9 10
# 累計(jì)求和
> cum_sum<-cumsum(x)
# 累計(jì)求積
> cum_prod<-cumprod(x)
# 拼接成data.frame
> data.frame(x,cum_sum,cum_prod)
? ? x cum_sum cum_prod
1? 1? ? ? 1? ? ? ? 1
2? 2? ? ? 3? ? ? ? 2
3? 3? ? ? 6? ? ? ? 6
4? 4? ? ? 10? ? ? 24
5? 5? ? ? 15? ? ? 120
6? 6? ? ? 21? ? ? 720
7? 7? ? ? 28? ? 5040
8? 8? ? ? 36? ? 40320
9? 9? ? ? 45? 362880
10 10? ? ? 55? 3628800
我們通常用累計(jì)計(jì)算拌滋,記錄中間每一步的過(guò)程朴沿,看到的數(shù)據(jù)處理過(guò)程的特征。
2.5 差分計(jì)算
差分計(jì)算败砂,是用向量的后一項(xiàng)減去前一項(xiàng)赌渣,所獲得的差值,差分的結(jié)果反映了離散量之間的一種變化昌犹。
> x<-1:10;x
[1]? 1? 2? 3? 4? 5? 6? 7? 8? 9 10
# 計(jì)算1階差分
> diff(x)
[1] 1 1 1 1 1 1 1 1 1
# 計(jì)算2階差分
> diff(x,2)
[1] 2 2 2 2 2 2 2 2
# 計(jì)算2階差分坚芜,迭代2次
> diff(x,2,2)
[1] 0 0 0 0 0 0
下面做一個(gè)稍微復(fù)雜一點(diǎn)的例子,通過(guò)差分來(lái)發(fā)現(xiàn)數(shù)據(jù)的規(guī)律斜姥。
# 對(duì)向量2次累積求和
> x <- cumsum(cumsum(1:10));x
[1]? 1? 4? 10? 20? 35? 56? 84 120 165 220
# 計(jì)算2階差分
> diff(x, lag = 2)
[1]? 9? 16? 25? 36? 49? 64? 81 100
# 計(jì)算1階差分鸿竖,迭代2次
> diff(x, differences = 2)
[1]? 3? 4? 5? 6? 7? 8? 9 10
# 同上
> diff(diff(x))
[1]? 3? 4? 5? 6? 7? 8? 9 10
2.6 分組計(jì)算
分組是SQL中,支持的一種數(shù)據(jù)變換的操作铸敏,對(duì)應(yīng)于group by的語(yǔ)法缚忧。
比如,我們寫一個(gè)例子杈笔。創(chuàng)建一個(gè)數(shù)據(jù)框有a,b,c的3列闪水,其中a,c列為數(shù)值型,b列為字符串蒙具,我們以b列分組敦第,求出a列與c的均值。
# 創(chuàng)建數(shù)據(jù)框
> df<-data.frame(a=1:5,b=c('A','A','B','B','A'),c=rnorm(5));df
? a b? ? ? ? ? c
1 1 A? 1.28505418
2 2 A -0.04687263
3 3 B? 0.25383533
4 4 B? 0.70145787
5 5 A -0.11470372
# 執(zhí)行分組操作
> aggregate(. ~ b, data = df, mean)
? b? ? ? ? a? ? ? ? c
1 A 2.666667 0.3744926
2 B 3.500000 0.4776466
同樣的數(shù)據(jù)集店量,以b列分組芜果,對(duì)a列求和,對(duì)c列求均值融师。當(dāng)對(duì)不同列右钾,進(jìn)行不同的操作時(shí),我們同時(shí)也需要換其他函數(shù)來(lái)處理。
# 加載plyr庫(kù)
> library(plyr)
# 執(zhí)行分組操作
> ddply(df,.(b),summarise,
+? ? ? sum_a=sum(a),
+? ? ? mean_c=mean(c))
? b sum_a? ? ? mean_c
1 A? ? 8 -0.05514761
2 B? ? 7? 0.82301276
生成的結(jié)果舀射,就是按b列進(jìn)行分組后窘茁,a列求和,c列求均值脆烟。
2.7 分裂計(jì)算
分裂計(jì)算山林,是把一個(gè)向量按照一列規(guī)則,拆分成多個(gè)向量的操作邢羔。
如果你想把1:10的向量驼抹,按照單雙數(shù),拆分成2個(gè)向量拜鹤。
> split(1:10, 1:2)
$`1`
[1] 1 3 5 7 9
$`2`
[1]? 2? 4? 6? 8 10
另外框冀,可以用因子類型來(lái)控制分裂。分成2步操作敏簿,第一步先分成與數(shù)據(jù)集同樣長(zhǎng)度的因子明也,第二步進(jìn)行分裂,可以把一個(gè)大的向量拆分成多個(gè)小的向量惯裕。
# 生成因子規(guī)則
> n <- 3; size <- 5
> fat <- factor(round(n * runif(n * size)));fat
[1] 2 3 2 1 1 0 0 2 0 1 2 3 1 1 1
Levels: 0 1 2 3
# 生成數(shù)據(jù)向量
> x <- rnorm(n * size);x
[1]? 0.68973936? 0.02800216 -0.74327321? 0.18879230 -1.80495863? 1.46555486? 0.15325334? 2.17261167? 0.47550953
[10] -0.70994643? 0.61072635 -0.93409763 -1.25363340? 0.29144624 -0.44329187
# 對(duì)向量以因子的規(guī)則進(jìn)行拆分
> split(x, fat)
$`0`
[1] 1.4655549 0.1532533 0.4755095
$`1`
[1]? 0.1887923 -1.8049586 -0.7099464 -1.2536334? 0.2914462 -0.4432919
$`2`
[1]? 0.6897394 -0.7432732? 2.1726117? 0.6107264
$`3`
[1]? 0.02800216 -0.93409763
2.8 排序
排序是所有數(shù)據(jù)操作中温数,最常見(jiàn)一種需求了。在R語(yǔ)言中蜻势,你可以很方便的使用排序的功能撑刺,并不用考慮時(shí)間復(fù)雜度與空間復(fù)雜度的問(wèn)題,除非你自己非要用for循環(huán)來(lái)實(shí)現(xiàn)咙边。
對(duì)向量進(jìn)行排序。
# 生成一個(gè)亂序的向量
> x<-sample(1:10);x
[1]? 6? 2? 5? 1? 9 10? 8? 3? 7? 4
# 對(duì)向量排序
> x[order(x)]
[1]? 1? 2? 3? 4? 5? 6? 7? 8? 9 10
以數(shù)據(jù)框某一列進(jìn)行排序次员。
> df<-data.frame(a=1:5,b=c('A','A','B','B','A'),c=rnorm(5));df
? a b? ? ? ? ? c
1 1 A? 1.1780870
2 2 A -1.5235668
3 3 B? 0.5939462
4 4 B? 0.3329504
5 5 A? 1.0630998
# 自定義排序函數(shù)
> order_df<-function(df,col,decreasing=FALSE){
+? ? df[order(df[,c(col)],decreasing=decreasing),]
+ }
# 以c列倒序排序
> order_df(df,'c',decreasing=TRUE)
? a b? ? ? ? ? c
1 1 A? 1.1780870
5 5 A? 1.0630998
3 3 B? 0.5939462
4 4 B? 0.3329504
2 2 A -1.5235668
排序的操作败许,大多都是基于索引來(lái)完成的,用order()函數(shù)來(lái)生成索引淑蔚,再匹配的數(shù)據(jù)的數(shù)值上面市殷。
2.9 去重與找重
去重,是把向量中重復(fù)的元素過(guò)濾掉刹衫。找重醋寝,是把向量中重復(fù)的元素找出來(lái)。
> x<-c(3:6,5:8);x
[1] 3 4 5 6 5 6 7 8
# 去掉重復(fù)元素
> unique(x)
[1] 3 4 5 6 7 8
# 找到重復(fù)元素带迟,索引位置
> duplicated(x)
[1] FALSE FALSE FALSE FALSE? TRUE? TRUE FALSE FALSE
# 找到重復(fù)元素
> x[duplicated(x)]
[1] 5 6
2.10 轉(zhuǎn)置
轉(zhuǎn)置是一個(gè)數(shù)學(xué)名詞音羞,把行和列進(jìn)行互換,一般用于對(duì)矩陣的操作仓犬。
# 創(chuàng)建一個(gè)3行5列的矩陣
> m<-matrix(1:15,ncol=5);m
? ? [,1] [,2] [,3] [,4] [,5]
[1,]? ? 1? ? 4? ? 7? 10? 13
[2,]? ? 2? ? 5? ? 8? 11? 14
[3,]? ? 3? ? 6? ? 9? 12? 15
# 轉(zhuǎn)置后嗅绰,變成5行3列的矩陣
> t(m)
? ? [,1] [,2] [,3]
[1,]? ? 1? ? 2? ? 3
[2,]? ? 4? ? 5? ? 6
[3,]? ? 7? ? 8? ? 9
[4,]? 10? 11? 12
[5,]? 13? 14? 15
2.11 過(guò)濾
過(guò)濾,是對(duì)數(shù)據(jù)集按照某種規(guī)則進(jìn)行篩選,去掉不符合條件的數(shù)據(jù)窘面,保留符合條件的數(shù)據(jù)翠语。對(duì)于NA值的操作,主要都集中在了過(guò)濾操作和填充操作中财边,因此就不在單獨(dú)介紹NA值的處理了肌括。
# 生成數(shù)據(jù)框
> df<-data.frame(a=c(1,NA,NA,2,NA),
+? ? b=c('B','A','B','B',NA),
+? ? c=c(rnorm(2),NA,NA,NA));df
? a? ? b? ? ? ? ? c
1? 1? ? B -0.3041839
2 NA? ? A? 0.3700188
3 NA? ? B? ? ? ? NA
4? 2? ? B? ? ? ? NA
5 NA ? ? ? ? NA
# 過(guò)濾有NA行的數(shù)據(jù)
> na.omit(df)
? a b? ? ? ? ? c
1 1 B -0.3041839
# 過(guò)濾,保留b列值為B的數(shù)據(jù)
> df[which(df$b=='B'),]
? a b? ? ? ? ? c
1? 1 B -0.3041839
3 NA B? ? ? ? NA
4? 2 B? ? ? ? NA
過(guò)濾酣难,類似與SQL語(yǔ)句中的 WHERE 條件語(yǔ)句谍夭,如果你用100個(gè)以上的過(guò)濾條件,那么你的程序就會(huì)比較復(fù)雜了鲸鹦,最好想辦法用一些巧妙的函數(shù)或者設(shè)計(jì)模式慧库,來(lái)替換這些過(guò)濾條件。
2.12 填充
填充馋嗜,是一個(gè)比較有意思的操作齐板,你的原始數(shù)據(jù)有可能會(huì)有缺失值NA,在做各種計(jì)算時(shí)葛菇,就會(huì)出現(xiàn)有問(wèn)題甘磨。一種方法是,你把NA值都去掉眯停;另外一種方法是济舆,你把NA值進(jìn)行填充后再計(jì)算。那么在填充值時(shí)莺债,就有一些講究了滋觉。
把NA值進(jìn)行填充。
# 生成數(shù)據(jù)框
> df<-data.frame(a=c(1,NA,NA,2,NA),
+? ? ? b=c('B','A','B','B',NA),
+? ? ? c=c(rnorm(2),NA,NA,NA));df
? a? ? b? ? ? ? ? c
1? 1? ? B? 0.2670988
2 NA? ? A -0.5425200
3 NA? ? B? ? ? ? NA
4? 2? ? B? ? ? ? NA
5 NA ? ? ? ? NA
# 把數(shù)據(jù)框a列的NA齐邦,用9進(jìn)行填充
> na.fill(df$a,9)
[1] 1 9 9 2 9
# 把數(shù)據(jù)框中的NA椎侠,用1進(jìn)行填充
> na.fill(df,1)
? ? a? ? ? b? ? ? c? ? ? ? ?
[1,] " 1"? "B"? ? " 0.2670988"
[2,] "TRUE" "A"? ? "-0.5425200"
[3,] "TRUE" "B"? ? "TRUE"? ? ?
[4,] " 2"? "B"? ? "TRUE"? ? ?
[5,] "TRUE" "TRUE" "TRUE"? ?
填充時(shí),有時(shí)并不是用某個(gè)固定的值措拇,而是需要基于某種規(guī)則去填充我纪。
# 生成一個(gè)zoo類型的數(shù)據(jù)
> z <- zoo(c(2, NA, 1, 4, 5, 2), c(1, 3, 4, 6, 7, 8));z
1? 3? 4? 6? 7? 8
2 NA? 1? 4? 5? 2
# 對(duì)NA進(jìn)行線性插值
> na.approx(z)
? ? ? 1? ? ? ? 3? ? ? ? 4? ? ? ? 6? ? ? ? 7? ? ? ? 8
2.000000 1.333333 1.000000 4.000000 5.000000 2.000000
# 對(duì)NA進(jìn)行線性插值
> na.approx(z, 1:6)
? 1? 3? 4? 6? 7? 8
2.0 1.5 1.0 4.0 5.0 2.0
# 對(duì)NA進(jìn)行樣條插值
> na.spline(z)
? ? ? ? 1? ? ? ? 3? ? ? ? 4? ? ? ? 6? ? ? ? 7? ? ? ? 8
2.0000000 0.1535948 1.0000000 4.0000000 5.0000000 2.0000000
另外,我們可以針對(duì)NA的位置進(jìn)行填充丐吓,比如用前值來(lái)填充或后值來(lái)填充浅悉。
> df
? a? ? b? ? ? ? ? c
1? 1? ? B? 0.2670988
2 NA? ? A -0.5425200
3 NA? ? B? ? ? ? NA
4? 2? ? B? ? ? ? NA
5 NA ? ? ? ? NA
# 用當(dāng)前列中,NA的前值來(lái)填充
> na.locf(df)
? a b? ? ? ? ? c
1? 1 B? 0.2670988
2? 1 A -0.5425200
3? 1 B -0.5425200
4? 2 B -0.5425200
5? 2 B -0.5425200
# 用當(dāng)前列中券犁,NA的后值來(lái)填充
> na.locf(df,fromLast=TRUE)
? a b? ? ? ? ? c
1? 1 B? 0.2670988
2? 2 A -0.5425200
3? 2 B? ? ?
4? 2 B? ? ?
2.13 計(jì)數(shù)
計(jì)數(shù)术健,是統(tǒng)計(jì)同一個(gè)值出現(xiàn)的次數(shù)。
# 生成30個(gè)隨機(jī)數(shù)的向量
> set.seed(0)
> x<-round(rnorm(30)*5);x
[1]? 6 -2? 7? 6? 2 -8 -5 -1? 0 12? 4 -4 -6 -1 -1 -2? 1 -4? 2 -6 -1? 2? 1? 4? 0? 3? 5 -3 -6? 0
# 統(tǒng)計(jì)每個(gè)值出現(xiàn)的次數(shù)
> table(x)
x
-8 -6 -5 -4 -3 -2 -1? 0? 1? 2? 3? 4? 5? 6? 7 12
1? 3? 1? 2? 1? 2? 4? 3? 2? 3? 1? 2? 1? 2? 1? 1
用直方圖畫出粘衬。
> hist(x,xlim = c(-10,13),breaks=20)
2.14 統(tǒng)計(jì)分布
統(tǒng)計(jì)分布苛坚,是用來(lái)判斷數(shù)據(jù)是否是滿足某種統(tǒng)計(jì)學(xué)分布比被,如果能夠驗(yàn)證了,那么我們就可以用到這種分布的特性來(lái)理解我們的數(shù)據(jù)集的情況了泼舱。常見(jiàn)的連續(xù)型的統(tǒng)計(jì)分布有9種等缀,其中最常用的就是正態(tài)分布的假設(shè)
runif() :均勻分布
rnorm() :正態(tài)分布
rexp() :指數(shù)分布
rgamma() :伽馬分布
rweibull() :韋伯分布
rchisq() :卡方分布
rf() :F分布
rt() :T分布
rbeta() :貝塔分布
統(tǒng)計(jì)模型定義的回歸模型,就是基于正態(tài)分布的做的數(shù)據(jù)假設(shè)娇昙,如果殘差滿足正態(tài)分布尺迂,模型的指標(biāo)再漂亮都是假的。
下面用正態(tài)分布冒掌,來(lái)舉例說(shuō)明一下噪裕。假設(shè)我們有一組數(shù)據(jù),是人的身高信息股毫,我們知道平均身高是170cm膳音,然后我們算一下,這組身高數(shù)據(jù)是否滿足正態(tài)分布铃诬。
# 生成身高數(shù)據(jù)
> set.seed(1)
> x<-round(rnorm(100,170,10))
> head(x,20)
[1] 164 172 162 186 173 162 175 177 176 167 185 174 164 148 181 170 170 179 178 176
# 畫出散點(diǎn)圖
> plot(x)
通過(guò)散點(diǎn)圖來(lái)觀察祭陷,發(fā)現(xiàn)數(shù)據(jù)是沒(méi)有任何規(guī)律。接下來(lái)趣席,我們進(jìn)行正態(tài)分布的檢驗(yàn)兵志,Shapiro-Wilk進(jìn)行正態(tài)分布檢驗(yàn)。
> shapiro.test(x)
Shapiro-Wilk normality test
data:? x
W = 0.99409, p-value = 0.9444
該檢驗(yàn)原假設(shè)為H0:數(shù)據(jù)集符合正態(tài)分布宣肚,統(tǒng)計(jì)量W為想罕。統(tǒng)計(jì)量W的最大值是1,越接近1霉涨,表示樣本與正態(tài)分布越匹配按价。p值,如果p-value小于顯著性水平α(0.05)笙瑟,則拒絕H0楼镐。檢驗(yàn)結(jié)論:
W接近1,p-value>0.05逮走,不能拒絕原假設(shè)鸠蚪,所以數(shù)據(jù)集S符合正態(tài)分布今阳!
同時(shí)师溅,我們也可以用QQ圖,來(lái)做正態(tài)分布的檢驗(yàn)盾舌。
圖中墓臭,散點(diǎn)均勻的分布在對(duì)角線,則說(shuō)明這組數(shù)據(jù)符合正態(tài)分布妖谴。
為了窿锉,更直觀地對(duì)正態(tài)分布的數(shù)據(jù)進(jìn)行觀察酌摇,我們可以用上文中計(jì)數(shù)操作時(shí),使用的直方圖進(jìn)行觀察
圖中嗡载,散點(diǎn)均勻的分布在對(duì)角線窑多,則說(shuō)明這組數(shù)據(jù)符合正態(tài)分布。
為了洼滚,更直觀地對(duì)正態(tài)分布的數(shù)據(jù)進(jìn)行觀察埂息,我們可以用上文中計(jì)數(shù)操作時(shí),使用的直方圖進(jìn)行觀察遥巴。
> hist(x,breaks=10)
通過(guò)計(jì)數(shù)的方法千康,發(fā)現(xiàn)數(shù)據(jù)形狀如鐘型,中間高兩邊低铲掐,中間部分的數(shù)量占了95%拾弃,這就是正態(tài)的特征。當(dāng)判斷出摆霉,數(shù)據(jù)是符合正態(tài)分布后豪椿,那么才具備了可以使用一些的模型的基礎(chǔ)。
2.15 數(shù)值分段
數(shù)值分段斯入,就是把一個(gè)連續(xù)型的數(shù)值型數(shù)據(jù)砂碉,按區(qū)間分割為因子類型的離散型數(shù)據(jù)。
> x<-1:10;x
[1]? 1? 2? 3? 4? 5? 6? 7? 8? 9 10
# 把向量轉(zhuǎn)換為3段因子刻两,分別列出每個(gè)值對(duì)應(yīng)因子
> cut(x, 3)
[1] (0.991,4] (0.991,4] (0.991,4] (0.991,4] (4,7]? ? (4,7]? ? (4,7]? ? (7,10]? ? (7,10]? ? (7,10]?
Levels: (0.991,4] (4,7] (7,10]
# 對(duì)因子保留2位精度增蹭,并支持排序
> cut(x, 3, dig.lab = 2, ordered = TRUE)
[1] (0.99,4] (0.99,4] (0.99,4] (0.99,4] (4,7]? ? (4,7]? ? (4,7]? ? (7,10]? (7,10]? (7,10]?
Levels: (0.99,4] < (4,7] < (7,10]
2.16 集合操作
集合操作,是對(duì)2個(gè)向量的操作磅摹,處理2個(gè)向量之間的數(shù)值的關(guān)系滋迈,找到包含關(guān)系、取交集户誓、并集饼灿、差集等。
# 定義2個(gè)向量x,y
> x<-c(3:8,NA);x
[1]? 3? 4? 5? 6? 7? 8 NA
> y<-c(NA,6:10,NA);y
[1] NA? 6? 7? 8? 9 10 NA
# 判斷x與y重復(fù)的元素的位置
> is.element(x, y)
[1] FALSE FALSE FALSE? TRUE? TRUE? TRUE? TRUE
# 判斷y與x重復(fù)的元素的位置
> is.element(y, x)
[1]? TRUE? TRUE? TRUE? TRUE FALSE FALSE? TRUE
# 取并集
> union(x, y)
[1]? 3? 4? 5? 6? 7? 8 NA? 9 10
# 取交集
> intersect(x, y)
[1]? 6? 7? 8 NA
# 取x有帝美,y沒(méi)有元素
> setdiff(x, y)
[1] 3 4 5
# 取y有碍彭,x沒(méi)有元素
> setdiff(y, x)
[1]? 9 10
# 判斷2個(gè)向量是否相等
> setequal(x, y)
[1] FALSE
2.17 移動(dòng)窗口
移動(dòng)窗口,是用來(lái)按時(shí)間周期觀察數(shù)據(jù)的一種方法悼潭。移動(dòng)平均庇忌,就是一種移動(dòng)窗口的最常見(jiàn)的應(yīng)用了。
在R語(yǔ)言的的TTR包中舰褪,支持多種的移動(dòng)窗口的計(jì)算皆疹。
runMean(x) :移動(dòng)均值
runSum(x) :移動(dòng)求和
runSD(x) :移動(dòng)標(biāo)準(zhǔn)差
runVar(x) :移動(dòng)方差
runCor(x,y) :移動(dòng)相關(guān)系數(shù)
runCov(x,y) :移動(dòng)協(xié)方差
runMax(x) :移動(dòng)最大值
runMin(x) :移動(dòng)最小值
runMedian(x):移動(dòng)中位數(shù)
下面我們用移動(dòng)平均來(lái)舉例說(shuō)明一下,移動(dòng)平均在股票交易使用的非常普遍占拍,是最基礎(chǔ)的趨勢(shì)判斷的根蹤指標(biāo)了略就。
# 生成50個(gè)隨機(jī)數(shù)
> set.seed(0)
> x<-round(rnorm(50)*10);head(x,10)
[1]? 13? -3? 13? 13? 4 -15? -9? -3? 0? 24
# 加載TTR包
> library(TTR)
# 計(jì)算周期為3的移動(dòng)平均值
> m3<-SMA(x,3);head(m3,10)
[1]? ? ? ? NA? ? ? ? NA? 7.6666667? 7.6666667 10.0000000? 0.6666667 -6.6666667 -9.0000000 -4.0000000
[10]? 7.0000000
# 計(jì)算周期為5的移動(dòng)平均值
> m5<-SMA(x,5);head(m5,10)
[1]? NA? NA? NA? NA? 8.0? 2.4? 1.2 -2.0 -4.6 -0.6
當(dāng)計(jì)算周期為3的移動(dòng)平均值時(shí)容握,結(jié)果的前2個(gè)值是NA梗掰,計(jì)算的算法是
(第一個(gè)值 + 第二個(gè)值 + 第三個(gè)值)? /3 = 第三個(gè)值的移動(dòng)平均值
(13? ? ? +? ? -3? +? ? 13)? ? /3 = 7.6666667
畫出圖形
> plot(x,type='l')
> lines(m3,col='blue')
> lines(m5,col='red')
圖中黑色線是原始數(shù)據(jù)紊遵,藍(lán)色線是周期為3的移動(dòng)平均值沐悦,紅色線是周期為5的移動(dòng)平均值。這3個(gè)線中崔兴,周期越大的越平滑颗祝,紅色線波動(dòng)是最小的,趨勢(shì)性是越明顯的恼布。如果你想更深入的了解移動(dòng)平均線在股票中的使用情況螺戳,請(qǐng)參考文章二條均線打天下。
2.18 時(shí)間對(duì)齊
時(shí)間對(duì)齊折汞,是在處理時(shí)間序列類型時(shí)常用到的操作倔幼。我們?cè)谧鼋鹑诹炕治鰰r(shí),經(jīng)常遇到時(shí)間不齊的情況爽待,比如某支股票交易很活躍损同,每一秒都有交易,而其他不太活躍的股票鸟款,可能1分鐘才有一筆交易膏燃,當(dāng)我們要同時(shí)分析這2只股票的時(shí)候,就需要把他們的交易時(shí)間進(jìn)行對(duì)齊何什。
# 生成數(shù)據(jù)组哩,每秒一個(gè)值
> a<-as.POSIXct("2017-01-01 10:00:00")+0:300
# 生成數(shù)據(jù),每59秒一個(gè)值
> b<-as.POSIXct("2017-01-01 10:00")+seq(1,300,59)
# 打印a
> head(a,10)
[1] "2017-01-01 10:00:00 CST" "2017-01-01 10:00:01 CST" "2017-01-01 10:00:02 CST" "2017-01-01 10:00:03 CST"
[5] "2017-01-01 10:00:04 CST" "2017-01-01 10:00:05 CST" "2017-01-01 10:00:06 CST" "2017-01-01 10:00:07 CST"
[9] "2017-01-01 10:00:08 CST" "2017-01-01 10:00:09 CST"
# 打印b
> head(b,10)
[1] "2017-01-01 10:00:01 CST" "2017-01-01 10:01:00 CST" "2017-01-01 10:01:59 CST" "2017-01-01 10:02:58 CST"
[5] "2017-01-01 10:03:57 CST" "2017-01-01 10:04:56 CST"
按分鐘進(jìn)行對(duì)齊处渣,把時(shí)間都對(duì)齊到分鐘線上伶贰。
# 按分鐘對(duì)齊
> a1<-align.time(a, 1*60)
> b1<-align.time(b, 1*60)
# 查看對(duì)齊后的結(jié)果
> head(a1,10)
[1] "2017-01-01 10:01:00 CST" "2017-01-01 10:01:00 CST" "2017-01-01 10:01:00 CST" "2017-01-01 10:01:00 CST"
[5] "2017-01-01 10:01:00 CST" "2017-01-01 10:01:00 CST" "2017-01-01 10:01:00 CST" "2017-01-01 10:01:00 CST"
[9] "2017-01-01 10:01:00 CST" "2017-01-01 10:01:00 CST"
> head(b1,10)
[1] "2017-01-01 10:01:00 CST" "2017-01-01 10:02:00 CST" "2017-01-01 10:02:00 CST" "2017-01-01 10:03:00 CST"
[5] "2017-01-01 10:04:00 CST" "2017-01-01 10:05:00 CST"
由于a1數(shù)據(jù)集,每分鐘有多條數(shù)據(jù)罐栈,取每分鐘的最后一條代表這分鐘就行黍衙。
> a1[endpoints(a1,'minutes')]
[1] "2017-01-01 10:01:00 CST" "2017-01-01 10:02:00 CST" "2017-01-01 10:03:00 CST" "2017-01-01 10:04:00 CST"
[5] "2017-01-01 10:05:00 CST" "2017-01-01 10:06:00 CST"
這樣子就完成了時(shí)間對(duì)齊,把不同時(shí)間的數(shù)據(jù)放到都一個(gè)維度中了荠诬。
3. 個(gè)性化的數(shù)據(jù)變換需求
我們上面已經(jīng)介紹了琅翻,很多種的R語(yǔ)言數(shù)據(jù)處理的方法,大多都是基于R語(yǔ)言內(nèi)置的函數(shù)或第三方包來(lái)完成的柑贞。在實(shí)際的工作中方椎,實(shí)際還有再多的操作,完全是各性化的凌外。
3.1 過(guò)濾數(shù)據(jù)框中辩尊,列數(shù)據(jù)全部為空的列
空值涛浙,通常都會(huì)給我們做數(shù)值計(jì)算康辑,帶來(lái)很多麻煩摄欲。有時(shí)候一列的數(shù)據(jù)都是空時(shí),我們需要先把這一個(gè)過(guò)濾掉疮薇,再進(jìn)行數(shù)據(jù)處理胸墙。
用R語(yǔ)言程序進(jìn)行實(shí)現(xiàn)
# 判斷哪列的值都是NA
na_col_del_df<-function(df){
? df[,which(!apply(df,2,function(x) all(is.na(x))))]?
}
# 生成一個(gè)數(shù)據(jù)集
> df<-data.frame(a=c(1,NA,2,4),b=rep(NA,4),c=1:4);df
? a? b c
1? 1 NA 1
2 NA NA 2
3? 2 NA 3
4? 4 NA 4
# 保留非NA的列
> na_col_del_df(df)
? a c
1? 1 1
2 NA 2
3? 2 3
4? 4 4
3.2 替換數(shù)據(jù)框中某個(gè)區(qū)域的數(shù)據(jù)
我們想替換數(shù)據(jù)框中某個(gè)區(qū)域的數(shù)據(jù),那么應(yīng)該怎么做呢按咒?
找到第一個(gè)數(shù)據(jù)框中迟隅,與第二個(gè)數(shù)據(jù)框中匹配的行的值作為條件,然后替換這一行的其他指定列的值励七。
> replace_df<-function(df1,df2,keys,vals){
+? ? row1<-which(apply(mapply(match,df1[,keys],df2[,keys])>0,1,all))
+? ? row2<-which(apply(mapply(match,df2[,keys],df1[,keys])>0,1,all))
+? ? df1[row1,vals]<-df2[row2,vals]
+? ? return(df1)
+ }
# 第一個(gè)數(shù)據(jù)框
> df1<-data.frame(A=c(1,2,3,4),B=c('a','b','c','d'),C=c(0,4,0,4),D=1:4);df1
? A B C D
1 1 a 0 1
2 2 b 4 2
3 3 c 0 3
4 4 d 4 4
# 第二個(gè)數(shù)據(jù)框
> df2<-data.frame(A=c(1,3),B=c('a','c'),C=c(9,9),D=rep(8,2));df2
? A B C D
1 1 a 9 8
2 3 c 9 8
# 定義匹配條件列
> keys=c("A","B")
# 定義替換的列
> vals=c("C","D")
# 數(shù)據(jù)替換
> replace_df(df1,df2,keys,vals)
? A B C D
1 1 a 9 8
2 2 b 4 2
3 3 c 9 8
4 4 d 4 4
其實(shí)不管R語(yǔ)言中智袭,各種內(nèi)置的功能函數(shù)有多少,自己做在數(shù)據(jù)處理的時(shí)候掠抬,都要自己構(gòu)建很多DIY的函數(shù)吼野。
3.3 長(zhǎng)表和寬表變換
長(zhǎng)寬其實(shí)是一種類對(duì)于標(biāo)準(zhǔn)表格形狀的描述,長(zhǎng)表變寬表两波,是把一個(gè)行數(shù)很多的表瞳步,讓其行數(shù)減少,列數(shù)增加腰奋,寬表變長(zhǎng)表单起,是把一個(gè)表格列數(shù)減少行數(shù)增加。
長(zhǎng)表變寬表劣坊,指定program列不動(dòng)嘀倒,用fun列的每一行,生成新的列局冰,再用time列的每個(gè)值進(jìn)行填充括儒。
# 創(chuàng)建數(shù)據(jù)框
> df<-data.frame(
+? ? program=rep(c('R','Java','PHP','Python'),3),
+? ? fun=rep(c('fun1','fun2','fun3'),each = 4),
+? ? time=round(rnorm(12,10,3),2)
+ );df
? program? fun? time
1? ? ? ? R fun1 10.91
2? ? Java fun1? 6.59
3? ? ? PHP fun1? 9.26
4? Python fun1 11.17
5? ? ? ? R fun2 12.27
6? ? Java fun2? 6.61
7? ? ? PHP fun2? 7.28
8? Python fun2? 9.39
9? ? ? ? R fun3? 9.22
10? ? Java fun3 11.20
11? ? PHP fun3 13.40
12? Python fun3 10.67
# 加載reshape2庫(kù)
> library(reshape2)
# 長(zhǎng)表變寬表
> wide <- reshape(df,v.names="time",idvar="program",timevar="fun",direction = "wide");wide
? program time.fun1 time.fun2 time.fun3
1? ? ? R? ? 10.91? ? 12.27? ? ? 9.22
2? ? Java? ? ? 6.59? ? ? 6.61? ? 11.20
3? ? PHP? ? ? 9.26? ? ? 7.28? ? 13.40
4? Python? ? 11.17? ? ? 9.39? ? 10.67
接下來(lái),進(jìn)行反正操作锐想,把寬表再轉(zhuǎn)換為長(zhǎng)表帮寻,還是使用reshape()函數(shù)。
# 寬表變?yōu)殚L(zhǎng)表
> reshape(wide, direction = "long")
? ? ? ? ? ? program? fun? time
R.fun1? ? ? ? ? ? R fun1? 8.31
Java.fun1? ? ? Java fun1? 8.45
PHP.fun1? ? ? ? PHP fun1 10.49
Python.fun1? Python fun1 10.45
R.fun2? ? ? ? ? ? R fun2? 8.72
Java.fun2? ? ? Java fun2? 4.15
PHP.fun2? ? ? ? PHP fun2 11.47
Python.fun2? Python fun2 13.25
R.fun3? ? ? ? ? ? R fun3 10.10
Java.fun3? ? ? Java fun3 13.86
PHP.fun3? ? ? ? PHP fun3? 9.96
Python.fun3? Python fun3 14.64
我們?cè)趯挶磙D(zhuǎn)換為長(zhǎng)表時(shí)赠摇,可以指定想轉(zhuǎn)換部分列固逗,而不是所有列,這樣就需要增加一個(gè)參數(shù)進(jìn)行控制藕帜。比如烫罩,只變換time.fun2,time.fun3列到長(zhǎng)表洽故,而不變換time.fun1列贝攒。
> reshape(wide, direction = "long", varying =3:4)
? ? ? program time.fun1? time id
1.fun2? ? ? R? ? ? 8.31? 8.72? 1
2.fun2? ? Java? ? ? 8.45? 4.15? 2
3.fun2? ? PHP? ? 10.49 11.47? 3
4.fun2? Python? ? 10.45 13.25? 4
1.fun3? ? ? R? ? ? 8.31 10.10? 1
2.fun3? ? Java? ? ? 8.45 13.86? 2
3.fun3? ? PHP? ? 10.49? 9.96? 3
4.fun3? Python? ? 10.45 14.64? 4
這樣子的轉(zhuǎn)換變形,是非常有利于我們從多角度來(lái)看數(shù)據(jù)的时甚。
3.4 融化
融化隘弊,用于把以列進(jìn)行分組的數(shù)據(jù)哈踱,轉(zhuǎn)型為按行存儲(chǔ),對(duì)應(yīng)數(shù)據(jù)表設(shè)計(jì)的概念為梨熙,屬性表設(shè)計(jì)开镣。
我們?cè)O(shè)計(jì)一下標(biāo)準(zhǔn)的二維表結(jié)構(gòu),然后按屬性表的方式進(jìn)行轉(zhuǎn)換咽扇。
# 構(gòu)建數(shù)據(jù)集
> df<-data.frame(
+? id=1:10,
+? x1=rnorm(10),
+? x2=runif(10,0,1)
+ );df
? id? ? ? ? ? x1? ? ? ? ? x2
1? 1? 1.78375335 0.639933473
2? 2? 0.26424700 0.250290845
3? 3 -1.83138689 0.963861236
4? 4 -1.77029220 0.451004465
5? 5 -0.92149552 0.322621217
6? 6? 0.88499153 0.697954226
7? 7? 0.68905343 0.002045145
8? 8? 1.35269693 0.765777220
9? 9? 0.03673819 0.908817646
10 10? 0.49682503 0.413977373
# 融合邪财,以id列為固定列
> melt(df, id="id")
? id variable? ? ? ? value
1? 1? ? ? x1? 1.783753346
2? 2? ? ? x1? 0.264247003
3? 3? ? ? x1 -1.831386887
4? 4? ? ? x1 -1.770292202
5? 5? ? ? x1 -0.921495517
6? 6? ? ? x1? 0.884991529
7? 7? ? ? x1? 0.689053430
8? 8? ? ? x1? 1.352696934
9? 9? ? ? x1? 0.036738187
10 10? ? ? x1? 0.496825031
11? 1? ? ? x2? 0.639933473
12? 2? ? ? x2? 0.250290845
13? 3? ? ? x2? 0.963861236
14? 4? ? ? x2? 0.451004465
15? 5? ? ? x2? 0.322621217
16? 6? ? ? x2? 0.697954226
17? 7? ? ? x2? 0.002045145
18? 8? ? ? x2? 0.765777220
19? 9? ? ? x2? 0.908817646
20 10? ? ? x2? 0.413977373
這個(gè)操作其實(shí)在使用ggplot2包畫圖時(shí),會(huì)被經(jīng)常用到质欲。因?yàn)間gplot2做可視化時(shí)畫多條曲線時(shí)树埠,要求的輸入的數(shù)據(jù)格式必須時(shí)屬性表的格式。
3.5 周期分割
周期分割嘶伟,是基于時(shí)間序列類型數(shù)據(jù)的處理弥奸。比如黃金的交易,你可以用1天為周期來(lái)觀察奋早,也可以用的1小時(shí)為周期來(lái)觀察盛霎,也可以用1分鐘為周期來(lái)看。
下面我們嘗試先生成交易數(shù)據(jù)耽装,再對(duì)交易數(shù)據(jù)進(jìn)行周期的分割愤炸。本例僅為周期分割操作的示范,數(shù)據(jù)為隨機(jī)生成的掉奄,請(qǐng)不要對(duì)數(shù)據(jù)的真實(shí)性較真规个。
# 加載xts包
> library(xts)
# 定義生成每日交易數(shù)據(jù)函數(shù)
> newTick<-function(date='2017-01-01',n=30){
+? newDate<-paste(date,'10:00:00')
+? xts(round(rnorm(n,10,2),2),order.by=as.POSIXct(newDate)+seq(0,(n-1)*60,60))
+ }
假設(shè)我們要生成1年的交易數(shù)據(jù),先產(chǎn)生1年的日期向量姓建,然后循環(huán)生成每日的數(shù)據(jù)诞仓。
# 設(shè)置交易日期
> dates<-as.Date("2017-01-01")+seq(0,360,1)
> head(dates)
[1] "2017-01-01" "2017-01-02" "2017-01-03" "2017-01-04" "2017-01-05" "2017-01-06"
# 生成交易數(shù)據(jù)
> xs<-lapply(dates,function(date){
+? newTick(date)
+ })
# 查看數(shù)據(jù)靜態(tài)結(jié)構(gòu)
> str(head(xs,2))
List of 2
$ :An ‘xts’ object on 2017-01-01 10:00:00/2017-01-01 10:29:00 containing:
? Data: num [1:30, 1] 9.98 9.2 10.21 9.08 7.82 ...
? Indexed by objects of class: [POSIXct,POSIXt] TZ:
? xts Attributes:?
NULL
$ :An ‘xts’ object on 2017-01-02 10:00:00/2017-01-02 10:29:00 containing:
? Data: num [1:30, 1] 9.41 13.15 6.07 10.12 10.37 ...
? Indexed by objects of class: [POSIXct,POSIXt] TZ:
? xts Attributes:?
NULL
# 轉(zhuǎn)型為xts類型
> df<-do.call(rbind.data.frame, xs)
> xdf<-as.xts(df)
> head(xdf)
? ? ? ? ? ? ? ? ? ? ? V1
2017-01-01 10:00:00? 9.98
2017-01-01 10:01:00? 9.20
2017-01-01 10:02:00 10.21
2017-01-01 10:03:00? 9.08
2017-01-01 10:04:00? 7.82
2017-01-01 10:05:00 10.47
現(xiàn)在有了數(shù)據(jù),那么我們可以對(duì)數(shù)據(jù)日期速兔,按周期的分割了墅拭,從而生成開(kāi)盤價(jià)、最高價(jià)涣狗、最低價(jià)谍婉、收盤價(jià)。這里一樣會(huì)用到xts包的函數(shù)镀钓。
# 按日進(jìn)行分割穗熬,對(duì)應(yīng)高開(kāi)低收的價(jià)格
> d1<-to.period(xdf,period='days');head(d1)
? ? ? ? ? ? ? ? ? ? xdf.Open xdf.High xdf.Low xdf.Close
2017-01-01 10:29:00? ? 9.98? ? 13.74? ? 5.35? ? 13.34
2017-01-02 10:29:00? ? 9.41? ? 13.54? ? 6.07? ? ? 9.76
2017-01-03 10:29:00? ? 12.11? ? 13.91? ? 7.16? ? 10.75
2017-01-04 10:29:00? ? 10.43? ? 14.02? ? 6.31? ? 12.10
2017-01-05 10:29:00? ? 11.51? ? 13.97? ? 6.67? ? 13.97
2017-01-06 10:29:00? ? 10.57? ? 12.81? ? 4.30? ? ? 5.16
# 按月進(jìn)行分割
> m1<-to.period(xdf,period='months');m1
? ? ? ? ? ? ? ? ? ? xdf.Open xdf.High xdf.Low xdf.Close
2017-01-31 10:29:00? ? 9.98? ? 16.40? ? 3.85? ? 10.14
2017-02-28 10:29:00? ? 8.25? ? 16.82? ? 4.17? ? 11.76
2017-03-31 10:29:00? ? 10.55? ? 15.54? ? 2.77? ? ? 9.61
2017-04-30 10:29:00? ? 9.40? ? 16.13? ? 3.84? ? 11.77
2017-05-31 10:29:00? ? 13.79? ? 16.74? ? 3.97? ? 10.25
2017-06-30 10:29:00? ? 9.29? ? 16.15? ? 4.38? ? ? 7.92
2017-07-31 10:29:00? ? 5.39? ? 16.09? ? 4.55? ? ? 9.88
2017-08-31 10:29:00? ? 5.76? ? 16.34? ? 3.27? ? 10.86
2017-09-30 10:29:00? ? 9.56? ? 16.40? ? 3.58? ? 10.09
2017-10-31 10:29:00? ? 8.64? ? 15.50? ? 3.23? ? 10.26
2017-11-30 10:29:00? ? 9.20? ? 15.38? ? 3.00? ? 10.92
2017-12-27 10:29:00? ? 6.99? ? 16.22? ? 3.87? ? ? 8.87
# 按7日進(jìn)行分割
> d7<-to.period(xdf,period='days',k=7);head(d7)
? ? ? ? ? ? ? ? ? ? xdf.Open xdf.High xdf.Low xdf.Close
2017-01-07 10:29:00? ? 9.98? ? 15.54? ? 4.30? ? 10.42
2017-01-14 10:29:00? ? 11.38? ? 14.76? ? 5.74? ? ? 9.17
2017-01-21 10:29:00? ? 9.57? ? 16.40? ? 3.85? ? 11.91
2017-01-28 10:29:00? ? 10.51? ? 14.08? ? 4.66? ? 10.97
2017-02-04 10:29:00? ? 10.43? ? 16.69? ? 4.53? ? ? 6.09
2017-02-11 10:29:00? ? 11.98? ? 15.23? ? 5.04? ? 11.57
最后,通過(guò)可視化把不同周期的收盤價(jià)丁溅,畫到一個(gè)圖中唤蔗。
> plot(d1$xdf.Close)
> lines(d7$xdf.Close,col='red',lwd=2)
> lines(m1$xdf.Close,col='blue',lwd=2)
從圖中,可以看出切換為不同的周期,看到的形狀是完全不一樣的妓柜。黑色線表示以日為周期的箱季,紅色線表示以7日為周期的,藍(lán)色線表示以月為周期的领虹。
從本文的介紹來(lái)看,要做好數(shù)據(jù)處理是相當(dāng)不容易的求豫。你要知道數(shù)據(jù)是什么樣的塌衰,業(yè)務(wù)邏輯是什么,怎么寫程序以及數(shù)據(jù)變形蝠嘉,最后怎么進(jìn)行BI展示最疆,表達(dá)出正確的分析維度。試試R語(yǔ)言蚤告,忘掉程序員的思維努酸,換成數(shù)據(jù)的思維,也許繁瑣的數(shù)據(jù)處理工作會(huì)讓你開(kāi)心起來(lái)杜恰。
本文所介紹的數(shù)據(jù)處理的方法获诈,及個(gè)性化的功能函數(shù),我已經(jīng)發(fā)布為一個(gè)github的開(kāi)源項(xiàng)目心褐,項(xiàng)目地址為:https://github.com/bsspirit/RTransform歡迎大家試用舔涎,共同完善。