用R處理一組數據的三種方式

USArrests是R附帶的一個數據集,如今咱們須要建立一個factor向量urbancat,若是UrbanPop列的某個值在中位數之上,就把urbancat對應位置的值設爲1,不然設爲0。程序員

 

這種數據處理任務實在太簡單了,一個for循環就能搞定。首先,咱們計算一下UrbanPop的中位數:編程

urbanPop.median <- median(USArrests$UrbanPop)

而後,用rep函數初始化一個等長的urbancat向量:api

urbancat <- rep(x = 0, times = length(USArrests$UrbanPop))

接着,用for循環爲urbancat設置對應位置的值:編程語言

for (i in 1:length(urbancat)) {
  if (USArrests$UrbanPop[i] > urbanPop.median) {
      urbancat[i] <- 1
  }
}

以上代碼對於擁有命令式編程背景的同窗來講是很是親切天然的。值的提醒的是,若是urbancat的長度有可能爲0,那麼使用1:length(urbancat)可能會有非預期結果(你能夠試一下),這個時候咱們建議把1:length(urbancat)換成seq_along(urbancat)。函數式編程

 

對於擁有函數式編程背景的同窗,可使用purrr的map函數:函數

library(purrr)
urbancat <- map_dbl(USArrests$UrbanPop, function(x) if (x > urbanPop.median) 1 else 0)

map_dbl會在應用你傳入的匿名函數以後以double向量的方式返回結果。若是你喜歡用formula,也能夠把匿名函數換成formula:rest

urbancat <- map_dbl(USArrests$UrbanPop, ~ if (.x > urbanPop.median) 1 else 0)

這裏的.x表示map_dbl傳給你的UrbanPop列的某個值。code

 

在接觸R以前,我基本上都會選擇FP的作法,但在接觸R以後,我被它的向量化運算以及經過邏輯值取子集(logical subsetting)的作法深深吸引:orm

urbancat[USArrests$UrbanPop > urbanPop.median] <- 1

USArrests$UrbanPop是一個向量,而urbanPop.median是一個值,由於R默認支持向量化運算,因此拿USArrests$UrbanPop和urbanPop.median比較會自動轉化成拿USArrests$UrbanPop裏的每一個值和urbanPop.median,獲得一個和USArrests$UrbanPop等長的由邏輯值(T和F)組成的向量(F F T F T ......)。當咱們用這個邏輯值向量去索引urbancat時,就會取出邏輯值爲T的對應元素,這個時候,結合賦值運算就能夠把這些元素都設爲1了。blog

 

最後,要把urbancat變成factor向量,你能夠修改for循環或者map函數,但在R裏,你只需把urbancat傳給factor函數就好了:

urbancat <- factor(urbancat)

 

Ruby之父松本行弘在他的《松本行弘的程序世界》裏說過,「在語言學領域裏,有一個Sapir-Whirf假說,認爲語言能夠影響說話者的思想。也就是說,語言的不一樣,形成了思想的不一樣。程序員因爲使用的編程語言不一樣,他的思考方法和編寫出來的代碼都會受到編程語言的很大影響。」而這番話能夠很好地歸納我此時的感覺。

相關文章
相關標籤/搜索