用R處理一組數(shù)據(jù)的三種方式
USArrests是R附帶的一個(gè)數(shù)據(jù)集,現(xiàn)在我們需要?jiǎng)?chuàng)建一個(gè)factor向量urbancat,如果UrbanPop列的某個(gè)值在中位數(shù)之上,就把urbancat對(duì)應(yīng)位置的值設(shè)為1,否則設(shè)為0。
這種數(shù)據(jù)處理任務(wù)實(shí)在太簡(jiǎn)單了,一個(gè)for循環(huán)就能搞定。首先,我們計(jì)算一下UrbanPop的中位數(shù):
urbanPop.median <- median(USArrests$UrbanPop)
然后,用rep函數(shù)初始化一個(gè)等長(zhǎng)的urbancat向量:
urbancat <- rep(x = 0, times = length(USArrests$UrbanPop))
接著,用for循環(huán)為urbancat設(shè)置對(duì)應(yīng)位置的值:
for (i in 1:length(urbancat)) {
if (USArrests$UrbanPop[i] > urbanPop.median) {
urbancat[i] <- 1
}
}
以上代碼對(duì)于擁有命令式編程背景的同學(xué)來(lái)說(shuō)是非常親切自然的。值的提醒的是,如果urbancat的長(zhǎng)度有可能為0,那么使用1:length(urbancat)可能會(huì)有非預(yù)期結(jié)果(你可以試一下),這個(gè)時(shí)候我們建議把1:length(urbancat)換成seq_along(urbancat)。
對(duì)于擁有函數(shù)式編程背景的同學(xué),可以使用purrr的map函數(shù):
library(purrr) urbancat <- map_dbl(USArrests$UrbanPop, function(x) if (x > urbanPop.median) 1 else 0)
map_dbl會(huì)在應(yīng)用你傳入的匿名函數(shù)之后以double向量的方式返回結(jié)果。如果你喜歡用formula,也可以把匿名函數(shù)換成formula:
urbancat <- map_dbl(USArrests$UrbanPop, ~ if (.x > urbanPop.median) 1 else 0)
這里的.x表示map_dbl傳給你的UrbanPop列的某個(gè)值。
在接觸R之前,我基本上都會(huì)選擇FP的做法,但在接觸R之后,我被它的向量化運(yùn)算以及通過(guò)邏輯值取子集(logical subsetting)的做法深深吸引:
urbancat[USArrests$UrbanPop > urbanPop.median] <- 1
USArrests$UrbanPop是一個(gè)向量,而urbanPop.median是一個(gè)值,因?yàn)镽默認(rèn)支持向量化運(yùn)算,所以拿USArrests$UrbanPop和urbanPop.median比較會(huì)自動(dòng)轉(zhuǎn)化成拿USArrests$UrbanPop里的每個(gè)值和urbanPop.median,得到一個(gè)和USArrests$UrbanPop等長(zhǎng)的由邏輯值(T和F)組成的向量(F F T F T ......)。當(dāng)我們用這個(gè)邏輯值向量去索引urbancat時(shí),就會(huì)取出邏輯值為T的對(duì)應(yīng)元素,這個(gè)時(shí)候,結(jié)合賦值運(yùn)算就可以把這些元素都設(shè)為1了。
最后,要把urbancat變成factor向量,你可以修改for循環(huán)或者map函數(shù),但在R里,你只需把urbancat傳給factor函數(shù)就行了:
urbancat <- factor(urbancat)
Ruby之父松本行弘在他的《松本行弘的程序世界》里說(shuō)過(guò),“在語(yǔ)言學(xué)領(lǐng)域里,有一個(gè)Sapir-Whirf假說(shuō),認(rèn)為語(yǔ)言可以影響說(shuō)話者的思想。也就是說(shuō),語(yǔ)言的不同,造成了思想的不同。程序員由于使用的編程語(yǔ)言不同,他的思考方法和編寫出來(lái)的代碼都會(huì)受到編程語(yǔ)言的很大影響。”而這番話可以很好地概括我此時(shí)的感受。

浙公網(wǎng)安備 33010602011771號(hào)