[心得] 资料整理套件介绍-第三章 dplyr(下)

楼主: celestialgod (天)   2015-07-22 22:01:05
这章将要继续上章未完的dplyr
以下是这章主要内容:
A. 取唯一列:distinct, data.table:::unique
B. 列行运算:rowwise, plyr:::colwise
C. 值映射(对应修改):plyr:::mapvalues, plyr:::revalue
D. 其他函数:summarise_each, mutate_each
E. 特殊函数:plyr:::here
F. function with underscore suffix
1. 取唯一列
我在第一章 data.table提过 unique
distinct是一样的方法
就从data.table:::unique的例子开始
` R
DT = data.table(A = rbinom(5, 1, 0.5), B = rbinom(5, 1, 0.5))
# A B
# 1: 0 0
# 2: 0 1
# 3: 1 0
# 4: 0 1
# 5: 0 0
unique(DT)
# A B
# 1: 0 0
# 2: 0 1
# 3: 1 0
distinct(DT)
# A B
# 1: 0 0
# 2: 0 1
# 3: 1 0
unique(DT, by = "A")
# A B
# 1: 0 0
# 2: 1 0
distinct(DT, A)
# A B
# 1: 0 0
# 2: 1 0
`
但是如mutate, filter等函数
distinct也可以给由变量组成的其他条件来做取唯一列的动作
给个简单例子:
` R
distinct(DT, A*B)
# A B A * B
# 1: 0 0 0
`
2. 列行运算
mutate提供了列运算的函数 rowwise
虽然没有apply好写,不过效率确实好上不少
至少在chain上可以比较轻易地套用了
要介绍rowwise,还需要介绍do这个函数
do提供一些广泛的运算方式
像是你可以根据不同变量设立模型如范例所示
` R
set.seed(100)
DF = data.frame(A = sample(1:5, 50, TRUE),
y = rnorm(50), x = rnorm(50))
models = DF %>% group_by(A) %>% do(model = lm(y ~ x, data = .))
models %>% summarise(mse = mean(model$residuals**2))
# mse
# 1 0.07560431
# 2 0.03617592
# 3 0.71000090
# 4 0.35385491
# 5 1.39799410
DT = data.table(A = sample(1:5, 50, TRUE),
y = rnorm(50), x = rnorm(50))
models = group_by(DT, A) %>% do(model = lm(y ~ x, data = .))
models %>% rowwise %>% summarise(mse = mean(model$residuals**2))
# mse
# 1 0.8953635
# 2 0.3954457
# 3 0.1469698
# 4 0.6303710
# 5 0.2966472
`
data.table出来的结果不会自动group_by row
要自己手动加入rowwise,这点需要注意
do应该有更多应用,需要各位好好开发。
再来,给一个rowwise的应用:
` R
set.seed(100)
(DT = data.table(A = rnorm(5), B = rnorm(5), C = rnorm(5)))
# A B C
# 1: -0.50219235 0.3186301 0.08988614
# 2: 0.13153117 -0.5817907 0.09627446
# 3: -0.07891709 0.7145327 -0.20163395
# 4: 0.88678481 -0.8252594 0.73984050
# 5: 0.11697127 -0.3598621 0.12337950
DT %>% rowwise %>%
do(k = c(.$A, .$B, .$C)[between(c(.$A, .$B, .$C), 0, 1)]) %>%
summarise(size = length(k), sums = sum(k))
# size sums
# 1 2 0.4085162
# 2 2 0.2278056
# 3 1 0.7145327
# 4 2 1.6266253
# 5 2 0.2403508
`
colwise提供每一行的做一个动作的方法
其实等同于你用sapply做
只是它还可以让你选择你要做的column去做
简单例子如下:
` R
set.seed(100)
(DT = data.table(A = rnorm(5), B = rnorm(5), C = rnorm(5)))
# A B C
# 1: -0.50219235 0.3186301 0.08988614
# 2: 0.13153117 -0.5817907 0.09627446
# 3: -0.07891709 0.7145327 -0.20163395
# 4: 0.88678481 -0.8252594 0.73984050
# 5: 0.11697127 -0.3598621 0.12337950
colwise(function(x) c(mean(x), sd(x)))(DT)
# A B C
# 1 0.1600685 0.1890685 -0.6537084
# 2 0.8140039 0.7824803 0.5610936
colwise(function(x) c(mean(x), sd(x)), .cols = .(A, B))(DT)
# A B
# 1 0.1600685 0.1890685
# 2 0.8140039 0.7824803
f = function(x) quantile(x, c(0.05, 0.95))
colwise(f)(DT)
# A B C
# 1 -0.4175373 -0.7765657 -0.1433299
# 2 0.7357341 0.6353522 0.6165483
`
3. 值映射(对应修改)
这一节要介绍两个很好用的函数 plyr:::mapvalues, plyr:::revalue
这两个函数再处理资料时一定很常用到
我们再整理资料时,有时候会遇到奇异值
我们要把它改成我们想要的值时
大部分人应该都会遇到这个问题
或是有时候我们需要组别整并时也会遇到
给一个简单的example
` R
DT = data.table(col1 = sample(c("A", "B", "N"), 30, TRUE),
col2 = sample(c("A1", "B3", "C4", "U9", "Z5"), 30, TRUE),
col3 = sample(-2:2, 30, TRUE))
DT2 = copy(DT)
## example 1 - 当初keyin资料出问题,col1出现了"N"这个值,我们要通通改成NA
## 此处提供数种方法做
set(DT, which(DT$col1 == "N"), "col1", NA)
DT2 %>% mutate(col1 = ifelse(col1 == "N", NA, col1)) # transform同理
DT2 %>% mutate(col1 = revalue(col1, c(N = NA)))
DT2 %>% mutate(col1 = mapvalues(col1, "N", NA))
## example 2 - 我们想要把col2做调整 A1 改成 B3, U9改成Z5
## 这里就直接提供用revalue以及mapvalues的方法
DT2 %>% mutate(col2 = revalue(col2, c(A1 = "B3", U9 = "Z5")))
DT2 %>% mutate(col2 = mapvalues(col2, c("A1", "U9"), c("B3", "Z5")))
## example 3 - 当初keyin时不小心搞错col3的-2跟2的正负号,我们要把-2跟2做互换
DT2 %>% mutate(col3 = mapvalues(col3, c(-2, 2), c(2, -2)))
`
最后提示几个重点,
revalue可以用在factor跟character上面,不能用在数值上
mapvalues可以用在integer, double跟character上面,factor要先转chr
4. 其他函数
这两个函数 summarise_each, mutate_each,我自己也很少用
我提供一些例子做操作,先用简单的例子
` R
DT = data.table(X = rnorm(100), Y = rnorm(100))
DT %>% summarise_each(funs(c(median(.), mean(.))))
# X Y
# 1: -0.02923809 0.08238550
# 2: -0.09154615 0.05153845
DT = data.table(X = c(3,2), Y = c(1, 4))
DT %>% mutate_each(funs(half = . / 2))
# X Y
# 1: 1.5 0.5
# 2: 1.0 2.0
`
这例子只是很简单的介绍他们的功能
可能需要时间来累积看看是否有什么好方法去用这两个函数
5. 特殊函数
介绍一个我觉得很有趣的函数 here
here可以帮助你再使用sapply系列时
可以使用mutate等
提一个简单的例子
` R
DTs = resplicate(5, data.table(A = rnorm(5)), simplify = FALSE)
DTs = lapply(DTs, here(mutate), Asq = A**2)
`
6. function with underscore suffix
本章最后一个重点
怎么使用像是filter_, select_, mutate_, ...这些以_结尾的function
这些以_结尾的function提供使用者使用string作为input
中间执行的过程透过 lazyeval 来执行
(其实dplyr大部分函数都透过这个套件)
来看几个简单的例子
` R
DT = data.table(A = rnorm(5), B = rnorm(5))
DT %>% select_("A")
DT %>% select(A)
DT %>% mutate(C = A*B)
(DT2 = DT %>% mutate_("A*B") %>% setnames("A*B", "C"))
`
这几个例子应该可以很简单的解释有_的函数要怎么使用
最后给个.dots的用法,这个代表说你可以制作适当的string放入
` R
DT = data.table(x = rnorm(100), y = rnorm(100))
(DT %<>% mutate_(.dots = c("x^2", "y^2")) %>%
setnames(c("x^2", "y^2"), c("xsq", "ysq")))
DT %>% select_(.dots = c("y", "xsq"))
`
再给一个简单的例子
` R
DT = data.table(x1 = rnorm(100), x2 = rnorm(100))
cmds = paste0("x", 1:2, "^2")
newnames = c("xsq", "ysq")
DT %<>% mutate_(.dots = cmds) %>% setnames(cmds, newnames))
`
下一章应该会是最后一章了
主要内容是data.table中的 dcast跟melt
还有tidyr的 separate, spread, gather
[关键字]: dplyr

Links booklink

Contact Us: admin [ a t ] ucptt.com