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假说,认为语言能够影响说话者的思想。也就是说,语言的不一样,形成了思想的不一样。程序员因为使用的编程语言不一样,他的思考方法和编写出来的代码都会受到编程语言的很大影响。”而这番话能够很好地归纳我此时的感觉。