《R數(shù)據(jù)科學(xué)》||15-16章vectors向量數(shù)據(jù)概念+purrr循環(huán)迭代

r4ds

寫論文的間隙換換腦子繼續(xù)學(xué)習(xí)R4ds這本書。對R語言中的數(shù)據(jù)格式有了更加系統(tǒng)的認(rèn)識。這一章值得反復(fù)多看幾遍。

  1. 英文原版在線https://r4ds.had.co.nz/index.html
  2. 中文翻譯版已有售,建議紙質(zhì)版書籍隨時翻翻。電子版網(wǎng)盤分享 https://pan.baidu.com/s/1fkpqYahQHPkwx66XD2gGGg 提取碼: akct
  3. 最近才公布的課后習(xí)題參考答案https://jrnold.github.io/r4ds-exercise-solutions/
  4. Rstudio的一些便捷CheetSheetshttps://www.rstudio.com/resources/cheatsheets/
  5. 另外在寫代碼過程中Rstudio操作時的方便快捷鍵:賦值<- Alt+“減號” ;管道符%>% Ctrl+Shift+M

十五章, 向量vectors

一. 向量概括

向量vectors包括兩種:源自向量(atomic vectors)和列表(list)

  • 原子向量 :包括6種:logical,numeric(integer, double), character, complex, raw。向量種的各個值都是同種類型的;
  • 列表: 遞歸列表(recrusive list),
  • 拓展向量:向量中任意添加額外的元數(shù)據(jù)。

二. 原子向量

  1. 邏輯型(logical)包括三種:TRUE, FALSE, NA

  2. 數(shù)值型(numeric):默認(rèn)數(shù)值為雙精度型double;

    • 注意雙精度型double是近似值(approximations),所有的雙精度值都當(dāng)做是近似值處理,表示浮點(diǎn)數(shù)(floating point)
    • interger的特殊數(shù)據(jù)NA,double的特殊數(shù)據(jù)NA, NaN,Inf,-Inf需要以is.finite()等判斷
  3. 字符串(character):可以包含任意數(shù)量的數(shù)據(jù)。

三. 原子向量的操作

  1. 強(qiáng)制轉(zhuǎn)換:將一種原子強(qiáng)制轉(zhuǎn)化為另一種;或者系統(tǒng)自動轉(zhuǎn)化
    • 顯示型強(qiáng)制轉(zhuǎn)化as.numeric,as.character等;
    • 隱式強(qiáng)制轉(zhuǎn)化:聯(lián)系上下文context自動轉(zhuǎn)化,如logical———>numeric;
x <- sample(x = 20,size = 100,replace = T)
y <- x>10
mean(y);sum(y)
  1. 檢驗是否為某一原子向量:利用purrr包中的函數(shù)is_is_logical(), is_character

  2. 標(biāo)量與循環(huán)的規(guī)則:處理不同長度的向量會遵循 向量循環(huán)規(guī)則

  3. 向量命名:所有類型的向量都是可以命名的.向量完成后利用:purrr::set_names(x,nm=c("q","w","e"))命名。

  4. 向量的取子集:filter()函數(shù)對tibble使用,對于向量的篩選則使用[]。

    • 整數(shù)型數(shù)值向量進(jìn)行篩選:x[c(1,2,2,4)], x[c(-1,-2,-3)]
    • 使用邏輯向量取子集,提取出TRUE值對應(yīng)的元素??衫?strong>比較函數(shù)
    • 對命名向量可用字符取子集
    • x[] 代表選取x中的全部元素,對于矩陣十分重要x[2,],x[,-3]特殊的,[[]] 代表只提取單個元素。明確表示需要提取單個元素時使用。對于矩陣/dataframe來說,x[,c(2)]返回的仍然是一個df(特殊的list),而x[[,2]]返回的才是真正的原子向量

四. 列表(遞歸向量recrusive vectors)

  1. 列表保存層級結(jié)構(gòu),樹形結(jié)構(gòu)。str(),重點(diǎn)關(guān)注列表的結(jié)構(gòu)。
  2. 列表取子集 :
    • []提取子列表,返回的是一個子列表;可用邏輯向量,整數(shù)向量,字符向量提取。
    • 使用[[]]從列表中提取單個元素,并非子列表。
    • 直接使用$,作用相同于[[]]。綜合使用。x[[1]][[1]]
    • 注意于tibble之間使用的異同點(diǎn),tibble[1], tibble[[1]]
a <- list(a=1:3,b="a string",c=pi,d=list(-1,-5))
a[c(1:2)]
a["a"]
a[["a"]][1:2]

五. 特性:

  • 任何向量都可以通過其特性來附加任意元數(shù)據(jù)。
    泛型函數(shù):可以根據(jù)不同類型的輸入而進(jìn)行不同的操作。面向?qū)ο缶幊痰年P(guān)鍵。

六. 拓展向量:

利用基礎(chǔ)的原子向量和列表構(gòu)建出的另外一些重要的向量類型,稱為拓展向量,其具有類的附加特性。

  1. 因子,表示有次序的分類數(shù)據(jù)factor(c("ef","cd","ab"),levels=c("ab","cd","ef"))
  2. 日期和日期時間。

Charpter16_purrr

一. For循環(huán)

  • 需為輸出結(jié)果分配出足夠的空間。對循環(huán)效率十分重要。
  • 涉及的函數(shù)包括 vector("double",ncol(df)), seq_along(df), [[]]
###16.2 for循環(huán)
require(tidyverse)
df <- tibble(a=rnorm(10),
             b=rnorm(10),
             c=rnorm(10),
             d=rnorm(10))

output <- vector("double",ncol(df))
output
for (i in seq_along(df)) {
  output[i] <- median(df[[i]])
}
output


### exercise Alice the Camel
humps <- c("five", "four","three","two","one","no")
for (i in humps) {
  cat(str_c("Alice the camel has",rep(i,3),"horse",collapse = "\n"),"\n")
}

二. for循環(huán)的變體

  1. 修改現(xiàn)有對象:與自定義的函數(shù)function()一起使用。

    • 注意再循環(huán)loop中,所有for循環(huán)使用的都是[[]] ,明確表示是要處理單個元素。
  2. 循環(huán)模式:

    • 通過對數(shù)值索引進(jìn)行循環(huán),再通過x[[i]]提取相應(yīng)的值。
    • 通過對元素element索引。
    • 通過使用名稱索引for (i in names(x)),需要使用元素的名稱時使用。
  3. 未知的輸出長度。

    • 應(yīng)該將loop每次的結(jié)果保存再一個列表中,循環(huán)結(jié)束后再利用unlist() 或者purrr::flatten_dbl()組合成一個向量
    • 當(dāng)遇到類似的問題,如生成一個很長的字符串paste(out,collapse=""),或是個很大的數(shù)據(jù)框rbind_rows()。應(yīng)首先使用一個更復(fù)雜的對象來保存每次迭代的結(jié)果,最后再一次性的組合起來。
means <- c(0,1,2)
output <- double()
for (i in seq_along(means)) {
  n <- sample(100,1)
  output <- c(output,rnorm(n,mean = means[[i]])) ### 十分不高效,這里會復(fù)制上一次的所有數(shù)據(jù)。
}

##高效法 
out <- vector("list",length = length(means))
for (i in seq_along(means)){
  n <- sample(100,1)
  out[[i]] <- rnorm(n,mean = means[[i]])
}
unlist(out)
  1. 未知的輸入序列長度。利用while循環(huán)來實現(xiàn)。
####exercises
# 1.讀取文件,保存在大的數(shù)據(jù)框中
files <- dir(path = ".",pattern = "tsv$",full.names = F) ###匹配某一路徑下所有的文件。
data_list <- vector("list",length = length(files))
for (i in seq_along(files)) {
  data_list[[i]] <- read_delim(files[[i]],delim = "\t")
}
bind_rows(data_list)

#2.輸出所有df中數(shù)值列的均值及名稱show_mean(iris)
iris <- as_tibble(iris)
show_means <- function(df,digits=2){
  maxstr <- max(str_length(names(df)))
  for (i in names(df)) {
  if (is.numeric(df[[i]])) {
    cat(
      str_c(str_pad(str_c(i,":"),maxstr+1L,side = "right"),
            format(mean(df[[i]]),digits=2,nsmall=2),
                   sep=" "
              ),
     sep =  "\n"  
    )
  }
}
}

三. for循環(huán)與函數(shù)式編程

  • 函數(shù)式編程語言意味著可以先將for循環(huán)包裝在函數(shù)中。即將函數(shù)名作為參數(shù)傳入到另一個函數(shù)中
  • 利用purrr函數(shù),可以將復(fù)雜問題解決成子問題,然后再通過管道操作將這些問題的結(jié)果組合起來。
col_summary <- function(x,fun){
  out <- vector("double",length(x))
  for (i in seq_along(x)) {
    out[[i]]=fun(x[[i]])
  }
  out
}

四. 映射函數(shù) mapping function

purrr包函數(shù)map()(返回的是列表),map_lgl(),map_dbl(),map_chr()。map()第二個參數(shù)可以是公式,字符向量,整型向量,第三個參數(shù)為第二個函數(shù)中的附加參數(shù)。

  1. 快捷方式(shortcuts):對某個數(shù)據(jù)集中的每個分組都擬合一個線性模型。類似于factor中的一些功能。
  2. map(df,function(xxx) length(unique(xxx))——》map(df, ~ length(unique(.))) 因為需要一些更復(fù)雜的函數(shù)去實現(xiàn)一些功能
models <- mtcars %>% 
  split(.$cyl) %>% 
  map(function(df) lm(mpg ~ wt,data=df)) ##  df是一個匿名函數(shù),可任意命名。

  1. 在對列表中的各個子集內(nèi)部進(jìn)行篩選
out ###str(out)
map(out, ~ .[. > 0.8]) ###篩選每一列中大于0.8的數(shù)據(jù)。


  1. exercises中涉及的一些函數(shù):map(-2:2,rnorm, n=5), map(1:3,rnorm,mean=10).

五. 多參數(shù)映射mapping over multiple arguments

  1. map2(), pmap()對每一列的功能操作會涉及到多個參數(shù)時,就需要利用此函數(shù)。注意每次發(fā)生變化的參數(shù)放在函數(shù)功能的前面位置,值保持不變的參數(shù)放在函數(shù)的后面
mu <- list(5,10,-3)
map(mu, rnorm, n=5)
### map2 的應(yīng)用
sigma <- list(1,5,10)
map2(mu,sigma,rnorm,n=5)
### pmap()應(yīng)用,多個參數(shù)都未定,就將參數(shù)保存到大列表中
n <- list(3,5,8)
args <- list(n=n,sd=sigma,mean=mu)
pmap(args,rnorm)
  1. 多個參數(shù) 對于pmap()函數(shù),可以將多個輸入列表作為參數(shù)。且多個列表的長度一樣**可以轉(zhuǎn)換為tibble,確保每列都有名稱,且與其它列具有相同的長度 **

  2. 多個參數(shù),且多個映射函數(shù),利用invoke_map()函數(shù)。(invoke 調(diào)用)

六. 游走函數(shù),預(yù)測函數(shù),歸納與累計

  1. 游走函數(shù)walk,輸出保存多個文件時非常實用。walk(), pwalk
library(ggplot2)
plots <- mtcars %>% split(.$cyl) %>% 
  map( ~ ggplot(data = .,mapping = aes(mpg,wt))+geom_point())
  path=stringi::stri_c(names(plots),".pdf")
  
  pwalk(list(path,plots),ggsave,path=tempdir())

  1. 預(yù)測函數(shù)keep(), discard()函數(shù)可以保留輸入中預(yù)測值為TRUE和FALSE的元素。some(), every()分別用來確定預(yù)測值是否對某個元素為真。detect()找出預(yù)測值為真的第一個元素,detect_index()返回找到的元素的位置。

  2. 歸納約簡與累計 reduce/accumulate:復(fù)雜列表簡化為一個簡單列表。

vs <- list(c(1,2,3,4,5),
           c(1,2,3,4),
           c(1,2,3))
reduce(vs,intersect)

charpter21_ggplot2(graphics for communication)

  1. 標(biāo)簽labels:labs()
    • title="" 主標(biāo)題
    • subtitle="" 副標(biāo)題,添加附加信息;
    • caption= " " 描述數(shù)據(jù)來源 右下角添加信息
    • x=" ", y=" "坐標(biāo)軸信息
    • color= "" 圖例中的標(biāo)題
    • x= quote() 坐標(biāo)軸上使用數(shù)學(xué)公式
library(ggplot2)
require(tidyverse)
ggplot(mpg,aes(displ,hwy))+geom_point(aes(color=class))+labs(title = "aaaaa",subtitle = "bbbbb",caption = "cccc ",x="HWY",y="DISPL")
  1. 注釋Annotation:為單個或分組的觀測值添加標(biāo)簽。
    • filter(row_number(desc(hwy))==1) 篩選每個組中hwy數(shù)值最高的觀測observation。
    • geom_point() + geom_text(aes(label= ),data=)
    • 利用ggrepel包可以自動調(diào)整注釋標(biāo)簽的位置 geom_label_repel(aes(label=))
    • 將標(biāo)題加在圖形里的右上角角落上
    • 添加參考線geom_hline(),geom_vline(size=2,color=white)
    • 感興趣的點(diǎn)周圍添加個矩形 geom_rect()
    • 繪制箭頭,指向關(guān)注的數(shù)據(jù)點(diǎn)geom_segment()
library(ggplot2)
library(ggrepel)
best_in_class <- mpg %>% group_by(class) %>% filter(row_number(desc(hwy))==1)
ggplot(mpg,aes(displ,hwy))+geom_point(aes(color=class))+geom_text(mapping = aes(label=model),data = best_in_class)
### 利用ggrepel用較大的空心圓來強(qiáng)調(diào)
ggplot(mpg,aes(displ,hwy))+geom_point(aes(color=class))+geom_point(size=4,shape=1,data = best_in_class)+geom_label_repel(aes(label=model),data = best_in_class)

### 將標(biāo)題加在圖形里的右上角角落上。
label <- mpg %>% summarise(displ=max(displ),hwy=max(hwy),label="AAAA\nbbbbbbbb")
ggplot(mpg,aes(displ,hwy))+geom_point()+geom_text(aes(label=label),data = label,vjust="top",hjust="right")

  1. 標(biāo)度scale:控制從數(shù)據(jù)值到圖形屬性的映射。scale_x(圖形屬性名稱)_continuous()(連續(xù)型/離散型/時間/日期時間型)
    • 調(diào)整坐標(biāo)軸axis ticks: 刻度 scale_y_continuous(breaks=seq(1,40,by=5)),坐標(biāo)軸圖例項目scale_y_continuous(labels=NULL)
    • 圖例legend:theme(legend.position="none/right/left/top/bottom"), 控制圖例的顯示guides(guide_legend())
    • 標(biāo)度替換:對標(biāo)度進(jìn)行數(shù)學(xué)轉(zhuǎn)換。
    • 顏色的轉(zhuǎn)換:利用RColorBrewer/ggsci包,對于數(shù)量少的legend,可以添加形狀映射。
ggplot(mpg,aes(displ,hwy))+geom_point(aes(color=class))+geom_smooth(se=F,color="darkgrey")+theme(legend.position = "bottom")+guides(color=guide_legend(nrow = 1,override.aes = list(size=4)))
library(ggsci)
library(RColorBrewer)
ggplot(mpg,aes(displ,hwy))+geom_point(aes(color=drv))+scale_color_brewer(palette = "Set1")
ggplot(mpg,aes(displ,hwy))+geom_point(aes(color=drv,shape=drv))+scale_color_aaas()

  1. 縮放,控制圖形范圍。coord_cartesian()函數(shù)設(shè)置xlim和ylim的參數(shù)值。
  2. 主題(themes):定制圖形中的非數(shù)據(jù)元素。theme_bw(),theme_grey()(默認(rèn)),theme_classic(),theme_light()
  3. 保存圖形ggsave()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容