最近做项目遇到了一个实际数据清洗的问题,如何将连续数据按从大到小分成n类?刚开始我是打算用tidyverse包的,但是找不到合适的函数。只能通过较为笨拙的方法进行了。
之后通过stackoverflow网站[1]进行查询才发现原来有这么好用的窗口函数。
较为笨拙的方法
使用Rbase包中的数据框操作进行,首先随机产生一个数据框作为模拟数据。
temp <- data.frame(name=letters[1:12], value=rnorm(12), q=rep(NA, 12)) head(temp) # name value quartile # 1 a 2.55118169 NA # 2 b 0.79755259 NA # 3 c 0.16918905 NA # 4 d 1.73359245 NA # 5 e 0.41027113 NA # 6 f 0.73012966 NA
temp.sorted <- temp[order(temp$value), ] temp.sorted$q <- rep(1:4, each=12/4) temp <- temp.sorted[order(as.numeric(rownames(temp.sorted))), ] head(temp) # name value q # 1 a 2.55118169 4 # 2 b 0.79755259 3 # 3 c 0.16918905 2 # 4 d 1.73359245 4 # 5 e 0.41027113 2 # 6 f 0.73012966 3
使用dplyr包中的ntile()
首先构建一个数据框,包含a,b变量。以该数据框进行演示:
foo <- data.frame(a = 1:100, b = runif(100, 50, 200), stringsAsFactors = FALSE)
载入tidyverse包[2],内部包含了dplyr包[3]。然后使用管道函数,利用函数ntile()
构建新的列,列名为q。或者不用通道函数,直接加载dplyr
包也可以。
library(tidyverse) foo %>% mutate(q = ntile(b, 10)) # a b q #1 1 93.94754 2 #2 2 172.51323 8 #3 3 99.79261 3 #4 4 81.55288 2 #5 5 116.59942 5 #6 6 128.75947 6
参考资料
[1]
How to quickly form groups : https://stackoverflow.com/questions/4126326/how-to-quickly-form-groups-quartiles-deciles-etc-by-ordering-columns-in-a?noredirect=1
[2]
tidyverse包: https://www.tidyverse.org/
[3]
dplyr包: https://dplyr.tidyverse.org/