Jimmy那些事儿

R_数据处理_dplyr&reshape2&tidyr

  • dplyr:轻松地处理data.frame, data.table以及多种数据库为基础的数据,实现选择、变换、分组等
  • plry:轻松地在vector, list, data.frame之间做分组变换,实现拆分、变换、合并的操作
  • reshpae2:横向、纵向做数据变换

非特别标注,默认为dplyr包

准备工作

  • tbl_df(iris) :数据类型转化

    将数据转化为tbl类型,更易于查看

  • glimpse(iris):tbl数据的信息密集概括

  • View(iris):以电子表格的样式显示数据集

  • %>% :管道函数,将左边对象的第一个参数传递到右边的函数中

  • summary():数据统计摘要;区别对待不同类型的数据变量- (1)数值型:相关极值等信息;(2)名义型/有序型:显示的是各水平的频数值


重组数据

改变数据集的布局

布局转换 - reshpae2 (数据透视)

  • melt(data, id.vars, measure.vars, factorsAsStrings = TRUE):以id.vars为基准,转为长格式形式
    • melt(data, id=c(“”), measure=c(“”) ,variable.name=c(“”),value.name=c(“”))

id=c(“”,””) 或 id.vars=c() 以该变量为 [基准] 进行重构;其他的列均摞起来

measure=c(“”) 或 measure.vars=c() :组合进id列的变量;若measure缺失,表示所有字段

varaiable.name ,表示将 各个变量的列名 放在这个列下面;

value.name,表示对应观测值的具体数值

na.rm = FALSE,

factorsAsStrings = TRUE,将因子转化为字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
names(airquality) <- tolower(names(airquality))
View(airquality)
airquality_1 <- head(airquality,3)
aqm <- melt(airquality_1, id=c("month","day")) # 以该变量为 [基准] 进行重构;其他的列均 [摞起来]
> melt(airquality_1, id=c("month","day")) # measure缺失时,默认选择所有的列
month day variable value
1 5 1 ozone 41.0
2 5 2 ozone 36.0
3 5 3 ozone 12.0
4 5 1 solar.r 190.0
5 5 2 solar.r 118.0
6 5 3 solar.r 149.0
7 5 1 wind 7.4
8 5 2 wind 8.0
9 5 3 wind 12.6
10 5 1 temp 67.0
11 5 2 temp 72.0
12 5 3 temp 74.0
> melt(airquality_1, id =c("month","day"), measure=c("wind","temp"))
month day variable value
1 5 1 wind 7.4
2 5 2 wind 8.0
3 5 3 wind 12.6
4 5 1 temp 67.0
5 5 2 temp 72.0
6 5 3 temp 74.0


  • dcast(data, formula, fun.aggregate = NULL):以formula中的rowvar为基准列,重铸为宽格式 [excel统计表单的格式];若加上FUN,则为 [数据透视表] 的格式
    • dcast(data, ID~variable, mean)

dcast的功能相当于 group_by + summarise 的功能

formula , rowvar1+rowvar2 ~ colvar1+colvar2的格式;

  • rowvar :以此为基准的id列;
  • colvar :需要重构的变量列;将该变量中的元素 [分类] 映射到 [列] 上去
    • 运行后的结果:出现的变量,原本为变量的列名,融合后是不参与计算的;参与的是对应的value列

若整个formula表达是中,均没有出现 variable列,默认即对其他所有的列默认做 [统计计数length]

除非指定具体的FUN函数

fun.aggregate(聚合函数):直接列出聚合函数的名称;默认为计数 [length]

margins = NULL;向量形式的变量名字;

  • 若为TRUE,则计算所有的合计
  • margins= “colname” / “rowname” 即表达式中出现的变量名

subset = NULL;针对特定的变量类别做重铸;但需要加载plyr包去接收函数

  • 选择 行中分类值 或者 variable列中的分类 “length” 进行重铸
    • subset = .(variable=="length") 或者 subset = .(month == 5 )
    • subset = .(time < 10 & chick < 20)

fill = NULL; 填充NA的值

drop = TRUE;对缺失值的处理;drop or Not

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
names(airquality) <- tolower(names(airquality))
View(airquality)
aqm <- melt(airquality, id=c("month", "day"), na.rm=TRUE) # 除了month和day两列,其他列摞起来,为了等长,m和d列循环对齐
dcast(aqm, day + variable ~ month) # 保持day和variable不变,按month中的元素 [分类] 映射到列上去(若month有5、6两个月,则分别有2列)
dcast(aqm, variable + day ~ month) # 换一下顺序,重复的variable连在一起,对应不一样的day,这样的方式排列
dcast(aqm, day ~ variable + month) # 只保留day列
dcast(aqm, day+month ~ variable) # 还原为原本的样子
# 表达式中均未出现variable列,即默认把其他列的每一行看做一个整体进行计算-#
dcast(aqm, day ~ month) # 当整个formula表达是中,均没有出现 variable列,即对其他所有的列默认做长度计算length
day 5 6
1 1 4 3 # 表示day为1,month为5时,共有4个变量
2 2 4 3
3 3 4 3
4 4 4 3
dcast(aqm, day ~ month, mean) # 对所有没有出现的变量做函数mean
day 5 6
1 1 76.35000 124.20000
2 2 58.50000 123.56667
3 3 61.90000 108.36667
4 4 101.12500 93.06667
# -------加入计算:等价于group_by + summarise------------------------------#
## 正常情况下含variable
> dcast(aqm , month~variable)
Aggregation function missing: defaulting to length # 默认为计数
month ozone solar.r wind temp
1 5 26 27 31 31
2 6 9 29 29 29
> dcast(aqm , month~variable, mean)
month ozone solar.r wind temp
1 5 23.61538 181.2963 11.62258 65.54839
2 6 29.44444 191.9655 10.34483 78.96552
# ------加入合计:margins-------------------
> dcast(aqm , month~variable,sum, margins = T)
month ozone solar.r wind temp (all)
1 5 614 4895 360.3 2032 7901.3
2 6 265 5567 300.0 2290 8422.0
3 (all) 879 10462 660.3 4322 16323.3
dcast(aqm , month~variable,sum, margins = "month")
# --------加入子集的选取subset-------------------
library(plyr) # needed to access . function
dcast(aqm, variable ~ month, mean, subset = .(variable == "ozone"))
dcast(aqm, variable ~ month, mean, subset = .(month == 5))
names(ChickWeight) <- tolower(names(ChickWeight))
chick_m <- melt(ChickWeight, id=2:4, na.rm=TRUE)
dcast(chick_m, chick ~ time, mean, subset = .(time < 10 & chick < 20)) # 多条件选取
  • dcast 和 acast区别
1
2
3
4
5
> dcast(aqm, variable + month ~ day)
> acast(aqm, variable + month ~ day) # acast和dcast的功能基本上相同,只是dcast会把 [分组信息] 作为一列或几列显示,而acast会将其作为行名
> acast(aqm, day ~ month, mean) # 保留的列作为合并在一起作为列名(少了day列,不建议使用)
> acast(aqm, variable ~ month ~ day) # acast 多出来的功能,生成一个三维数组,按照day的值分成31个矩阵
>


  • t(x)转置
  • mtcars <- mtacrs[, c(12,1:11) ]列重新排序


排序

向量

  • sort(x, decreasing = FALSE, …):排序,返回值排序后的数值向量
  • order(…, na.last = TRUE, decreasing = FALSE):回值是对应“排名”的元素所在向量中的位置
  • rank(x, na.last = TRUE, ties.method = c(“average”, “first”, “last”, “random”, “max”, “min”)):求秩的函数,返回这个向量中对应元素的“排名”
1
2
3
4
5
6
7
8
9
10
> x<-c(97,93,85,74,32,100,99,67)
> sort(x)
[1] 32 67 74 85 93 97 99 100
> order(x)
[1] 5 8 4 3 2 1 7 6
> rank(x)
[1] 6 5 4 3 1 8 7 2


排序 - 数据框

  • arrange(mtcars, desc(mpg),var) :根据变量进行排序
  • arrange(flights, desc(dep_delay - arr_delay)):对计算的数据进行计算

默认为升序,aes

  • reorder(x, y [,FUN]) : 先将x转化为因子,再根据y进行排序;

x 与 y两者参数的长度必须一致;

FUN,表示将FUN运用于y,根据其结果对x进行排序

order = F/T ;若为T,表示将其转化为有序因子

  • 排序并因子化
1
2
3
4
5
tophit <- tophitters2001[1:25,]
nameorder <- arrange(tophit, lg, avg) %>% dplyr::select(., name) # 获得name变量的排序
tophit$name <- factor(tophit$name,levels=nameorder) # 将name转化为因子,且与nameorder一致
tophit$name <- reorder(tophit$name, nameorder) # 报错;因为nameorder的长度小于name


返回行/列名 - Basic

  • colnames(object):返回所有的名称
    • names(object)
  • rownames(object):返回所有的名称 [二维以上的任何对象]
    • row.names(object)


重命名列变量

  • rename(tbl, y=year):将变量名year变更为y
1
rename(data, newname=oldname) # 新的列名在前
  • select(df2tbl, x1 = x, y1 = y):选择变量时,重命名;x1为新的列名
  • fix(object):可以同时改变格式 numeric / character 【Basic】


  • data_frame(a=1:3, b=3:5):将向量合并为数据框


合并 & 分割 - tidyr

  • separate(data, col, into, sep=”[^[:alnum:]]+”, remove=TRUE, convert=FALSE, extra=”warm”, fill=”warm”)将一列分隔为几列

data:

col :待分隔的列

into=c(“”,””):新的列名

sep:分隔符;

  • 若为字符串,作为正则表达式进行匹配(默认)
  • 若为数值型,则根据位置进行匹配(-1代表最后一位)

remove =TRUE,移除原来的待分隔的列

convert=FALSE, 若为TRUE,则进行格式转换

  • separate_rows(data, …, sep=””, convert=FASLE):把一列分隔为若干行


  • unite(data, col, …, sep=”_”, remove=TRUE):把几列合并为一列

… : 指定需要合并的列名

col=”” :合并后新增的列名

1
unite(table, century, year, col="year", sep="")


因子


重编码&排名 - 参见 [创建新变量]


合并数据集

合并联接 - Join

等价于SQL中的join联接

  • inner_join(a, b,by=”x1”) :内联接 合并数据,仅保留匹配的数据
  • left_join(a, b, by=”x1”) :以a表为基准表,加入与a表中x1列匹配的数据集b的记录
  • right_join(a, b, by=”x1”) :以b表为基准表,加入与b表中x1列匹配的数据集b的记录
  • outer_join(a,b, by=”x1”):保留所有数据,所有行

by = NUll(默认);表示为 自联接,自动选取 [相同的列] 作为索引

  • by=c(‘col1’, ‘col2’):两个表中相同名称列的匹配,必须同时出现两个字段名
  • by=c(‘col1’ = ‘col2’) :两个表中不同名称列之间的匹配

copy=False(默认); 若为True, 当a与b不为同一张表,会自动创建一个y的表


集处理 - 行

  • intersect(y, z)均出现在数据集y和z中的记录行
  • union(y, z):出现在y或者z中的记录,自动删除重复的值
  • setdiff(y, z)出现在数据集y 而不在z中的记录行


合并与筛选

仅返回匹配列的记录

  • semi_join(a, b, by=”x1”): 数据集a中能与b匹配的记录,以a表中”x1”列的值为索引
  • anti_join(a, b, by=”x1”) :数据集a中能与b不能匹配的记录,以a表中”x1”列的值为索引


插入行/列

  • bind_rows(y, z)插入新行;把数据集 z 作为新的行添加到y中,但需要进行赋值
  • bind_cols(y, z)添加新列;把数据集 z 作为新的行添加到y中(注意:数据按所在位置匹配
1
y <- bind_rows(y,z)
  • rbind(a,b):
  • cbind(a,b):



数据选取

子集观测值 - 行

  • filter(tbl_df, cond & cond) :根据逻辑条件选取,使用 &或者| 来进行设置
    • filter(hflights_df, Month == 1, DayofMonth == 1)
    • filter(tbl_df, x %in% c(“a”,”b”)) :表示x中包含“a”或者“b”的值,返回为逻辑为真
    • filter(iris,Species!=”setosa”) / filter(iris,!Species %in% c(“setosa”)):排除某些行 !
    • filter() %>% select(., var)选中子集中的特定列

对于多条件的选择,需要完整条件的,然后使用集合运算符将条件拼接起来。

&|

==>=<>!=

%in%


  • sample_frac(iris, 0.5, replace=False):按比例进行随机选取
  • sample_n(iris, 10, replace=True) :按数量进行随机选取
1
## replace = False(默认),表示是否替换
  • slice(mtcars, n:n): 通过行数的位置进行选取, 等价于data[n:n, ]
  • top_n(mtcars, 1, desc(carb) )选取并排列前n条记录;相当于先按某变量进行排序,然后选择前n条记录。

    • top_n(tbl_df, n [,wt])

    若为分组数据,则按组排序

1
2
## wt,用于进行排序的变量,可选;若不指定,默认为最后一个变量
## -n,从底部开始选择n个数据
  • nth():第n个元素


非缺失值的提取

  • is.na() & !
1
2
3
4
mtcars[!is.na(mtcars$hp), ]
# is.na(mtcars$hp),返回逻辑值TRUE / FALSE
# ! 反转逻辑值
# [n, ] 选择行


满足特定条件的行

  • 字符串函数、is.na() 、 !
1
2
3
mtcars[!is.na(str_subset(mtcars$new, "^1.\\d*")),]
# str_subset(mtcars$new, "^1.\\d*") 提取出格式为 ^1.\\d 的观测行
# !is.na() 将其转为逻辑值,并反转逻辑值


子集变量 - 列

Selection drops variables that are not in the selection while renaming retains them

  • select(mtcars, hp) :通过列名或帮助函数选取列变量
    • select(tbl_df, mpg:hp):;选取在mpg和hp之间的连续多个变量 (包含mpg&hp;用:连接
    • select(tbl_df, -var) / select(tbl_df, -(var1:var4)):通过-排除某个变量列
  • select(tbl, xxx ):通过帮助函数进行选择
    • starts_with(“x”):列名中以元素x为首的列
    • ends_with(“x”):列名中以元素x结尾的列
    • contains(“x”):包含元素x的列
    • matches(“.t”):符合指定匹配正则表达式的列
    • one_of(c(“mpg,”hp”) ):名字在指定组中的列,等价于 select(tbl, mpg, hp)
    • everything():所有列,一般调整数据集中变量顺序时使用
      • select(df2tbl,y,everything()) #将变量y放到最前
    • num_range(“x”, 1:5):选取名为x1、x2、x3、x4、x5的列
  • select_if():选取不同条件的列
    • hflights %>% select_if(is.factor):选取hflights数据中为因子的列 / is.numeric
    • hflights %>% select_if(function(col) is.numeric(col) && mean(col) > 3.5):选取hflights数据中某一变量列 ??


唯一值&重复值

  • distinct(iris):删除重复记录
    • distinct(hflights_df, Month, .keep_all = TRUE)
1
## .keep_all = TRUE,指保留除Month以外的其它列的内容。默认的情况是不保存其他列的。

指各个变量列均相同的记录

  • unique(x):只对向量可用;或对各行中各变量完全相同的行取一行
  • duplicated(x): 判断是否重复,返回逻辑值TRUE/FALSE;
    • x[!duplicated(x)] :选取不重复值的值

返回data中所有不相同的值,然后在进行行选取data[x, ]

1
2
3
4
5
6
7
8
9
10
11
12
> x <- c(1:5, 3:7)
> duplicated(x)
[1] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE
# 删除各行中变量完全相同的值 = unique(x)
data <- data[!duplicated(data), ] --# 返回各列所有相同的值 data[duplicated(test),]
# 删除某变量中相同的值
data <- data[!duplicated(test[, "var"]), ]
# 删除某两个变量完全相同的行
data <- data[!duplicated(test[, c("var1","var2")], ]



创建新变量

根据是否删除原列进行区分

计算并添加新列

若要将多个单元格中的值合并,用stringr包中的str_c()

  • 运用$直接创建 mtcars$new <- sqtr(mtcars$carb)
  • mutate(tbl_df, var3=var1+var2, var4=var3+..):优势在于可对刚添加的列进行变换


  • mutate_at(.tbl, .vars, .funs, ..):对指定的列运行窗口函数

.vars :用 vars(colname,colname) 表示;也可以是序列的形式;vars(col1:col2);或者是位置的数量

A list of columns generated by vars(), or a character vector of column names, or a numeric vector of column positions.

1
2
> starwars %>% summarise_at(vars(height:mass), mean, na.rm = TRUE
>
  • mutate_all():对每一列运行窗口函数
  • mutate_if():对指定类型的列运行窗口函数

窗口函数:

min_rank # 排序,并列时,其他序号延号

dense_rank #无缝排序

row_number # 排序。并列时将并列数在前的序号在前

percent_rank # 把数据在[0,1]中重组,并排序

lead # 把除第一个值以外的所有元素提前,最后一位为NA

lag # 把除最后一位以外的所有数据延后,第一个元素为NA

between() # 数据在a、b之间

ntile # 把数据分为n分

cute_dist # 累计分布


cummean # 累积mean函数

cumsum # 累积sum函数

cusmax # 累积max函数

cusmin # 累积min函数

cumall # 累积all函数

cumany # 累积any函数

cumprod # 累计prod函数

pmax # 针对元素的max函数;返回输入中最大的值,并将其长度自动扩大到输入中长度最大的那个向量

pmin # 针对元素的min函数


计算并删除其他列

  • transmute(df, var3=var1+var2):该函数扩展新变量的同时,将删除原始变量,仅返回创建的新变量 ;常伴有na.rm=T

na.rm= True 计算时排除NA值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
> mutate(head(airquality),Temp=Temp - 32)
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 35 5 1
2 36 118 8.0 40 5 2
3 12 149 12.6 42 5 3
4 18 313 11.5 30 5 4
5 NA NA 14.3 24 5 5
6 28 NA 14.9 34 5 6
>transmute(head(airquality),Temp=Temp - 32)
Temp
1 35
2 40
3 42
4 30
5 24
6 34


排名

  • row_number():对于相同的值,位置在前的排名在前
  • min_rank():对于相同的值,均显示排名较前的值。
  • dense_rank():对于相同的值,类似于min_rank(),均显示排名较小的值;但与后一位之间没有间隔
  • percent_rank():将排名缩放为[0,1]之间的值
  • cume_dist()累计的分布函数
  • ntile(x,n):将x划分为n个组块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> x <- c(5, 1, 3, 2, 2, NA)
> row_number(x)
[1] 5 1 4 2 3 NA
> min_rank(x) # 相同的值,排名较前的值
[1] 5 1 4 2 2 NA
> dense_rank(x) # 相同的值,排名较前的值,但与后一位没有间隔
[1] 4 1 3 2 2 NA
> percent_rank(x)
[1] 1.00 0.00 0.75 0.25 0.25 NA
> cume_dist(x)
[1] 1.0 0.2 0.8 0.6 0.6 NA
> ntile(x, 2)
[1] 2 1 2 1 1 NA


其他

  • pmin/pmax(.., na.rm=FALSE):返回输入中最小/最大值的向量组合,并将其长度自动扩大到输入中长度最大的那个向量
    • min/max():只返回单一长度的值
1
2
> pmax(5:1,10)
[1] 10 10 10 10 10


重编码

if_else() & case_when() 适合进行重编码,但缺少对象的输入,可结合within()

因为recode是面向 [向量] 的函数

常规编码

within / $

  • within(x, {}) :对x中的对象做运算

    • within:能对原始数据进行修改,但仍需要赋值
    • with():不能对原始数据进行修改,创建的变量只能在花括号之内有效(即使进行赋值也是如此),
      • 通过换行(而非逗号)来分割
      • 可通过<<-进行全部变量的赋值
      • 若要查看对象,必须在with() 内部进行输出

    within(data,{exp}) :可直接输出对象

    with(data,{exp}) :执行后,没有输出对象

    with函数的返回值是原语句的返回值。within跟with功能相同,但返回值不同,within会返回所有修改生效后的原始数据结构(列表、数据框等)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
> aq<-with(head(airquality), {
+ lOzone <- log(Ozone)
+ Month <- factor(month.abb[Month])
+ cTemp <- round((Temp - 32) * 5/9, 1)
+ S.cT <- Solar.R / cTemp
+ rm(Day, Temp)
+ #head(aq)
+ })
> aq
NULL # 显示为NULL,即aq不存在
# 仍需要赋值
> aq<-within(head(airquality), { # Notice that multiple vars can be changed
+ lOzone <- log(Ozone)
+ Month <- factor(month.abb[Month])
+ cTemp <- round((Temp - 32) * 5/9, 1) # From Fahrenheit to Celsius
+ S.cT <- Solar.R / cTemp # using the newly created variable
+ rm(Day, Temp)
+ })
> aq
Ozone Solar.R Wind Month S.cT cTemp lOzone
1 41 190 7.4 May 9.793814 19.4 3.713572
2 36 118 8.0 May 5.315315 22.2 3.583519
3 12 149 12.6 May 6.394850 23.3 2.484907
4 18 313 11.5 May 18.742515 16.7 2.890372
5 NA NA 14.3 May NA 13.3 NA
6 28 NA 14.9 May NA 18.9 3.332205


recode& recode_factor

  • recode(.x, a= ‘apple’, .default = NULL, .missing = NULL):保持原有的顺序水平;
  • recode_factor(.x, …, .default = NULL, .missing = NULL, .ordered = FALSE)
  1. .x : 进行处理的向量
    • 对于数值型向量,你可以基于位置替换它
    • 对于字符串,你可以基于字符串的名称来替换它
  2. 指定替换的变量为字符串 a = 'apple' : a为对象中要变更的值;’apple’为变更后的值
  3. .default=NULL: 对未匹配的值不做变更
    • .default=NAcharacter用NA替换未匹配的
  • .default= ‘others’ : 可以指定替换的值
  • .default = level(x) :支持对默认的顺序进行因子化
  1. 指定替换的变量为数值,需要用点号`` : 例如: `2` =20 或 20L
  2. 指定替换的变量为字符串,则无需点号,也无需引号”” : x="d"
    • 若对象x为向量is.vector() ,若不加L,则对于未匹配的值默认用NA替换;加L,对其他未匹配的值不做变更;
  3. .missing = NULL(默认) :对缺失值NA不做处理,默认为NA
    • .missing = “missing”:指定具体的值对NA进行替换

若不指定替换的变量,默认按照位置顺序进行重编码;但对未匹配的值默认用NA替换


.order=FALSE(默认):若为TRUE,则创建有序的因子

当输入的向量是可比较的,它的因子会被重新定义为默认的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
## 指定替换的变量 - 字符串
> x <- sample(c("a", "b", "c"), 10, replace = TRUE)
> x
[1] "a" "a" "b" "b" "a" "b" "a" "a" "a" "c"
> recode(x, a = "Apple")
[1] "Apple" "Apple" "b" "b" "Apple" "b" "Apple" "Apple" "Apple" "c"
> recode(x, a = "Apple", .default = NA_character_)
[1] "Apple" "Apple" NA NA "Apple" NA "Apple" "Apple" "Apple" NA
## 指定替换的变量 - 数值型
> x <- c(1:5)
> recode(x, '2'= 20L, '4' = 40L) # 加上L之后,对未匹配的值不做变更
[1] 1 20 3 40 5
> recode(x, '2'= 20, '4' = 40)
[1] NA 20 NA 40 NA
## 若不指定替换的变量,默认按照顺序进行重编码
> recode(x, "a", "b", "c") # 但对未匹配的值默认用NA替换
[1] "a" "b" "c" NA NA NA
#--------recode_factor------------------------------------------#
> recode_factor(factor(letters[1:3]), b = "z", c = "y") # 当输入的向量是可比较的,它的因子会被重新定义为默认的
[1] a z y
Levels: z y a
  • Recode(var, recodes, as.factor.result, as.numeric.result=TRUE, levels) :car包中的Recode函数,用法与car包中的recode函数相同;无需通过指定car包来运行;

var:字符型、数值型、因子型 向量

recodes:字符串格式的重编码方式;即编码内容需用 引号" "包括起来,多个条件之间用分号;分隔

  • 单个变量:"0=NA"
  • 一组向量:"c(7,8,9)='high'"
  • 一组序列变量:"7:9='C'"
  • 未匹配的值: "else=NA"
  • 字符串变量:"'a'='b' " 若编码的内容为字符串格式,需要用引号括起来;而最外面的引号也是必不可少的

as.factor.result = T/F;当输入的var为因子格式时,默认为TRUE,否则默认为FALSE

as.numeric.result=T/F;当输入的var为数值格式时,默认为TRUE,否则默认为FALSE

levels:可选的,默认为原本的顺序


条件编码

  • if_else(cond, true_value, false_value, missing=NULL):对于逻辑值的重编码

cond : 条件

missing = NULL(默认); 若对缺失值替换为某个值,需指定 “x”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## 常规重编码
leadership<-within(leadership,{
agecat<-NA
agecat[age>75] <- “Elder”
agecat[age>=55 & age<=75] <- “Middle aged”
agecat[age<55]<-“young”
})
## 常规单列变化
y$new<- if_else(y$new<=1, 10, y$new)
# 搭配within使用
within(y,{
carb <- if_else(carb<=2,20,carb)
})

In while (i <= 10) { … :
报错:the condition has length > 1 and only the first element will be used

这里你的i应该是个向量,用 i <= 10来做条件的时候会出现很多个TRUE和FALSE,系统选用第一个作为标准


  • case_when(cond ~ “”, TRUE ~ “”)多条件的重编码
    • 类同于SQL的case when;多条件之间按顺序进行执行。
    • Each logical vector can either have length 1 or a common length.

~ :表示赋值

TRUE :类同于 Else的功能

配合list()!!!,将语句进行拼接,然后执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 多条件重编码
within(mpg, {
drv= case_when(drv == "4" ~ "4wd",
drv == "f" ~ "Font",
drv == "r" ~ "Rear")})
x <- 1:10
case_when(
x %% 3 == 0 ~ "fizz buzz",
x %% 5 == 0 ~ "fizz",
x %% 7 == 0 ~ "buzz",
TRUE ~ as.character(x)
)
## 创建一个新变量
starwars %>%
select(name:mass, gender, species) %>%
mutate(
type = case_when(
height > 200 | mass > 200 ~ "large",
species == "Droid" ~ "robot",
TRUE ~ "other"
)
)
# 配合list() 与 !!!,将语句进行拼接,然后执行
patterns <- list( # 先将语句拼接
TRUE ~ as.character(x),
x %% 5 == 0 ~ "fizz",
x %% 7 == 0 ~ "buzz",
x %% 35 == 0 ~ "fizz buzz"
)
case_when(!!! patterns) # 用 !!! 执行


缺失值

在计算频数时,NA记为一次

检查与判断

  • is.na(x):逻辑判断
  • colSums(is.na(x)):求该列缺失值的数量
  • mean(is.na(x)):求该列缺失值的比例
  • is.nan(x):判断不可能值
  • is.infinite(x) :判断无穷值
1
2
3
4
case_when(
is.na(colnames) ~ "0"
TRUE ~ "1"
)


移除

  • na.rm=T:在计算之前将缺失值移除,可用在函数内部
  • na.omit(x): 移除所有含缺失值所在的行 [删除整行]
1
2
# 用来存储没有缺失值的数据
newdata <- na.omit(mydata)


缺失值重编码

  • na_if(x, y):把对象x中的y替换为NA
1
2
3
4
5
> x <- c(1, -1, 0, 10)
[1] 1 -1 0 10
> na_if(x,0)
[1] 1 -1 NA 10
  • coalesce(x,y):把对象x中的NA替换为y

x, y :均为向量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 把x中的NA替换为y
> x <- sample(c(1:5, NA, NA, NA)); x
[1] 5 3 NA 4 2 NA 1 NA
> coalesce(x, 0L)
[1] 5 3 0 4 2 0 1 0
# 将NA匹配为对应位置的值 (y, z 两者长度必须相同)
> y <- c(1, 2, NA, NA, 5)
> z <- c(NA, NA, 3, 4, 5)
> coalesce(y, z)
[1] 1 2 3 4 5
# 配合list() 与 !!!,将语句进行拼接,然后执行
vecs <- list(
c(1, 2, NA, NA, 5),
c(NA, NA, 3, 4, 5)
)
coalesce(!!! vecs)



概述函数 - summarise

若要根据某个组别进行分组,必须先将data进行分组 group_by ;

或者直接使用plyr::ddply(data, ~var, summarise, newcol=…)

  • summarise(iris, avg=mean(Sepal.Length)) :对数据进行概述,并创建新的子集 (将数据概括为单行数值)
1
summarise(data, newcol = mean(col))
  • summarise_all(.tbl, .funs, …):对每一列运行概述概述
    • summarise_each(iris, funs(mean)) :对每一列运行概述函数
  • summarise_at(.tbl, .vars, .funs, …, .cols=NULL):对指定的列运行概述函数
    • summarise_at(mtcars, vars(hp,mpg), mean, …, .cols=NULL)

vars() : 表示需要进行概述的列

.funs的用法

  • 直接在函数中写明需要运行的函数 summarise(., vars(), mean)
  • 结合funs写出调用的函数 summarise(., vars(), funs(mean))
  • summarise_if(.tbl, .predicate, .funs):对指令类型的列运行概述函数

funs的用法

1
2
3
4
5
6
> summarise_all(df1[,-1],funs(mean,sum)) # 若出现两个及以上的函数,列名中自动添加后缀
> summarise_all(df1[,-1],funs(sum(.*2))) # 所有数据用.表示
> summarise_all(df1[,-1],funs(medi=median)) # 指定得到的列后缀名
> summarise_all(df1[,-1],funs("in"=median)) # 或者加引号 (因为in在R中表示其他含义)
> mutate_all(df1[,-1],funs(.^2))
>


min / max / mean / median / sd / var / sum / IQR (向量的四分位距离)

n (向量中元素的个数)/ n_distinct (不同元素的个数)

first / last / nth (向量的第n个值)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
name1 <- c("Bob","Mary","Jane","Kim")
weight <- c(60,65,45,55)
height <- c(170,165,140,135)
weta <- 1:4
df1 <- data.frame(name1,weight,height,weta);df1
## 需指定要进行计算的列
summarise(df1,avg_weight=mean(weight),avg_height=mean(height))
## 对选出来的 [每一列] 都进行计算
summarise_all(select(df1,-1), mean)
## 配合vars函数,一次选择多列
summarise_at(df1,vars(weight,height,weta),mean)
summarise_at(df1,vars(weight:weta),mean)
u <- c("weight","height")
summarise_at(df1,vars(one_of(u)),mean) # 可以接字符串向量
summarise_at(df1,u,mean) # 也可以直接接字符串向量
summarise_at(df1,u,mean,trim=1) # mean的参数可以接在后面
summarise_at(df1,vars(contains("eig")),mean) # 匹配含有的
summarise_at(df1,vars(matches(".t.")),mean) # 使用正则表达式
summarise_at(df1,vars(starts_with("w")),mean) # 匹配以此为开头的
summarise_at(df1,vars(ends_with("ht")),mean) # 匹配以此为结尾的
summarise_at(df1[,-1],vars(everything()),mean) # 选择所有列
## 检验出所有是数值的列,全部求均值
summarise_if(df1,is.numeric,mean)


  • count(iris, Species [, wt=Sepal.Length]) :计算变量中每一个特定值的行数/频率/求和 (带或不带权重)

    • 若出现wt,表示进行 [求和]
1
2
3
4
5
6
7
8
9
10
## wt="" 可选;若缺失,则计算频率
count(iris, Species) # 分组计算Species列中各类别的频量;类似于基本函数包中的table函数
## wt="",若指定某一列,则会通过计算非缺失值的总和来比对权重(weighted);
# wt = var2 , 表示按var中的类别来分组,计算var2中未缺失值的对应的 [求和]
count(iris, Species, wt=Sepal.Length) # 即按Species分组后,求对应Sepal.Length中的值的总和
--等价于 iris %>% group_by(., Species) %>% summarize(., sum(Sepal.Length))
## sort = False


计数

  • length(x):返回一组向量或因子的长度
1
2
3
4
5
6
7
8
## 返回对象的个数 或者 某个列的的观测值行数
length(object/data$col)
# 返回非空置的行数
length(na.omit(object/data$col))
# 返回对象的唯一值的行数
length(unique(data$col/object)) # 等价于 n_distinct()
  • nrow() / ncol()向量、数据或数据框的总行数/总列数
  • n():返回观测行的行数,不能单独使用(可被用于 summarise()、mutate()、filter()
  • n_distinct(x, na.rm=FALSE):返回不重复的行数
    • sum(!is.na()):计算非空值的行数
  • count() :[分组] 计数、求和 (参见上一内容)


分布

  • mean(x, na.rm=FALSE) :返回均值;
    • mean(!is.na()) :非空值的均值
  • median(x, na.rm=FASLE):返回中位数
  • sum(x, na.rm=FALSE):返回求和
  • range(object):值域
  • colSums(x) / rowSums(x):各列/行求和
  • colMeans(x) / rowMeans(x):各列/行求均值


位置与序列

  • first(x)/last(x):最前/后的值
  • nth(x, n):从开始数的第n个值
  • quantile(x, probs=seq(0, 1, 0.25), na.rm=FALSE):显示x中处于[0,0.25,0.5,0.75,1]的值

probs = seq(0,1, 0.25) 或者 = c(0.25,0.5) :指定要显示的所处位置的值

  • min/max(x, na.rm=FALSE):返回最大/最小值


趋势

  • IQR():四分位距离
  • var():方差
  • sd():标准差
  • mad():绝对均方差


数字处理

  • options(digits=7) :默认有效位数为7位
  • trunc(x):取整 trunc(3.531) [1] 3
    • floor(x):向下取整
    • ceiling(x):向上取整
  • sigif(x, digits=n):指定最小值的有效位数
  • abs(x):绝对值
  • x %% y :求余数
  • x^n:幂次方
  • exp(x):指数
  • ln(x) / log(x, y):对数
  • sqrt(x):平方根


分组

  • group_by(.data, …, add=FALSE):根据Species进行分组
    • group_by(mtacrs, cyl,vs )

… : 表示用于分组的列名;

add= FALSE(默认)

  • FALSE,表示会覆盖原来的分组,相当于对源数据重新分组;
  • 若为TRUE,则不覆盖,相当于在原来的基础上在进行分组;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
> ## 先对mtcars按cyl 进行分组
> by_cyl <- mtcars %>% groupby(cyl)
>
> # --------add=FALSE (默认)-------------------------#
> by_cyl %>% group_by(vs, am) %>% # add默认为FALSE,即对 mtcars进行 vs,am 两个变量进行分组;
> summarise_at(.,vars(new),funs(mean) )
> # A tibble: 4 x 3
> # Groups: vs [?]
> vs am new
> <dbl> <dbl> <dbl>
> 1 0 0 1.737751
> 2 0 1 2.115355
> 3 1 0 1.404061
> 4 1 1 1.177520
>
> # 与如上等价
> > group_by(mtcars, vs,am) %>% summarise_at(.,vars(new),funs(mean) )
> # A tibble: 4 x 3
> # Groups: vs [?]
> vs am new
> <dbl> <dbl> <dbl>
> 1 0 0 1.737751
> 2 0 1 2.115355
> 3 1 0 1.404061
> 4 1 1 1.177520
>
> # --------add=TRUE ----------------------#
> > by_cyl %>% group_by(vs, am, add=TRUE) %>%
> + summarise_at(.,vars(new),funs(mean) )
> # A tibble: 7 x 4
> # Groups: cyl, vs [?] # 分组变量有3个
> cyl vs am new
> <dbl> <dbl> <dbl> <dbl>
> 1 4 0 1 1.414214
> 2 4 1 0 1.276142
> 3 4 1 1 1.177520
> 4 6 0 1 2.149830
> 5 6 1 0 1.500000
> 6 8 0 0 1.737751
> 7 8 0 1 2.414214
>
> > group_by(mtcars, cyl,vs,am) %>% summarise_at(.,vars(new),funs(mean) )
> # A tibble: 7 x 4
> # Groups: cyl, vs [?] # 分组变量有3个
> cyl vs am new
> <dbl> <dbl> <dbl> <dbl>
> 1 4 0 1 1.414214
> 2 4 1 0 1.276142
> 3 4 1 1 1.177520
> 4 6 0 1 2.149830
> 5 6 1 0 1.500000
> 6 8 0 0 1.737751
> 7 8 0 1 2.414214
>

>

  • ungroup(iris)移除数据框的分组信息
  • group_by_all()
  • group_by_at(.tbl, .vars, .funs = list(), …, .add = FALSE)
    • group_by_at(df, vars(accept,weight)) %>% summarise(., var=mean(height),count=n())

group_by_at() 与 group_by 的区别,仅在与at中将分组的变量用 vars() 包含起来,利于查看

  • group_by_if()


分组与概述函数

  • iris %>% group_by(., Species) %>% summarise(., sum(Sepal.Length)):对每一个分组分别进行概述计算
  • iris %>% group_by(., Species) %>% mutate(., …):按组计算新变量


apply函数簇

apply函数本身就是解决数据循环处理的问题,为了面向不同的数据类型,不同的返回值,apply函数组成了一个函数族,包括了8个功能类似的函数。这其中有些函数很相似,有些也不是太一样的。

行/列常用的函数

  1. colMeans() / rowMeans()
  2. colSums / rowSums()

apply

apply 函数是代替for循环最常用的函数;

  • apply(x, margin, fun, …):按行或按列进行循环计算,对子元素进行迭代,并把子元素子元素以参数传递的形式给自定义的FUN函数中,并返回计算结果
    • apply函数将原本data-time的格式的按行输出后自动变为了字符串格式

X:数组array、矩阵matrix、数据框data.frame

MARGIN: 按行计算或按按列计算,1表示按行,2表示按列

FUN: 自定义的调用函数

…: 更多参数,可选

1
apply(head(data), 1, print) # 查看数据如何传递
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 对一个矩阵的每一行求和
> x<-matrix(1:12,ncol=3)
> apply(x,1,sum)
[1] 15 18 21 24
# 按行循环,让数据框的x1列加1,并计算出x1,x2列的均值
# 生成matrix
> x <- cbind(x1 = 3, x2 = c(4:1, 2:5)); x
x1 x2
[1,] 3 4
[2,] 3 3
[3,] 3 2
[4,] 3 1
[5,] 3 2
[6,] 3 3
[7,] 3 4
[8,] 3 5
# 自定义函数myFUN,第一个参数x为数据
# 第二、三个参数为自定义参数,可以通过apply的'...'进行传入。
> myFUN<- function(x, c1, c2) {
+ c(sum(x[c1],1), mean(x[c2]))
+ }
# 把数据框按行做循环,每行分别传递给myFUN函数,设置c1,c2对应myFUN的第二、三个参数
> apply(x,1,myFUN,c1='x1',c2=c('x1','x2'))
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 4.0 4 4.0 4 4.0 4 4.0 4
[2,] 3.5 3 2.5 2 2.5 3 3.5 4


lapply

通过lapply开头的第一个字母”l” 可以判断返回结果集的类型

  • lapply(x, fun, …):返回和x等长的列表list作为结果集

x : 列表list、数据框data.frame


sapply

sapply函数是一个简化版的lapply,sapply增加了2个参数simplify和USE.NAMES,主要就是让输出看起来更友好,返回值为向量,而不是list对象。

  • sapply(x, fun,…, simplify=TRUE, USE.NAMES=TRUE)

X : 数组、矩阵、数据框

FUN: 自定义的调用函数

…: 更多参数,可选

simplify: 是否数组化,当值array时,输出结果按数组进行分组

simplify =FALSE , 则返回列表

USE.NAMES: 如果X为字符串,TRUE设置字符串为数据名,FALSE不设置


vapply

vapply类似于sapply,提供了FUN.VALUE参数,用来控制返回值的行名

  • vapply(x, fun, FUN.VALUE=C(“”), …, USE.NAMES=TRUE)

X:数组、矩阵、数据框

FUN: 自定义的调用函数

FUN.VALUE: 定义返回值的行名row.names

…: 更多参数,可选

USE.NAMES: 如果X为字符串,TRUE设置字符串为数据名,FALSE不设置

1
2
3
4
5
6
7
8
9
10
# 生成数据集
> x <- data.frame(cbind(x1=3, x2=c(2:1,4:5)))
# 设置行名,4行分别为a,b,c,d
> vapply(x,cumsum,FUN.VALUE=c('a'=0,'b'=0,'c'=0,'d'=0))
x1 x2
a 3 2
b 6 3
c 9 7
d 12 12


tapply

  • tapply(x, index, fun=NULL, …, simplify=TRUE):用于分组的循环计算,通过INDEX参数可以把数据集X进行分组

X: 向量 (只能是向量)

INDEX: 用于分组的索引

FUN: 自定义的调用函数

…: 接收多个数据

simplify : 是否数组化,当值array时,输出结果按数组进行分组

1
2
3
4
# 通过iris$Species品种进行分组
> tapply(iris$Petal.Length,iris$Species,mean)
setosa versicolor virginica
1.462 4.260 5.552


plyr - 分隔-操作-合并

用来切割、计算、合并数据的包;根据不同的要求进行切割,对特定条件切割后的数据应用函数,并返回结果。

可以理解为对不同条件进行分组,然后计算,并返回结果

在一个函数内同时解决spilt-apply-combine的三个步骤

  1. Spilt:把要处理的数据分割成小的片段
  2. Apply:对每个小片段进行操作
  3. Combine:把片段重新组合
  • a*plyr(.data, .margins, .fun, …, .progress = “none”)
  • d*plyr(.data, .variables, .fun, …, .progress = “none”)
  • l*plyr(.data, .fun, …, .progress = “none”)

首字母代表输入的待处理的数据格式,第二个字母-输出的数据格式;


ddply

  • ddply(.data, .variables, .fun = NULL, …, .progress = “none”, .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL):
    • ddply()函数会自动的将分割后的每一小部分的计算结果汇总,以data.frame的格式保存

.data:要操作的原始数据集,比如baby_name

.variables :按照某个变量,对数据集分割

可以是字符串向量形式"cylinders" 或 c("mpg","hp"),也可以是表达式形式 ~ cylindes 或 ~ cylinders + model_year也可以写成.(year)的形式

.fun :具体执行操作的函数,对分割后的每一个子数据集,调用该函数

第四个参数可选,表示第三个参数对应函数所需的额外参数

1
2
3
4
5
6
## 用transfrom添加一个新列;
# 增加一列反映每种车与其他 [所在组] 的油耗均值之间的偏差
auto <- ddply(auto, .(cylinders), transform, mpg.deviation=round(mpg - mean(mpg),2 ))
## plyr配合summarise使用
ddply(auto, .(cylinders), summarise, freq=length(cylinders), meanmpg= mean(mpg))


控制流

重复和循环

  • for结构for (var in seq) statement
    • 循环执行某语句statement,直到某个变量var的值不在包含在序列seq中为止
1
for (i in 1:10) print("hello")
  • while结构while (cond) statment
    • 必须确保cond中的条件语句能【被改变】(即它在某个时刻不在为真),否则循环将永不停止


条件执行

  • if-else结构if (cond) statement 或者 for (cond) statement1 else statement2
1
if (!is.factor(grade)) gerade <- as.factor(grade) else print("Grade already is a factor")
  • ifelse结构ifelse(cond, statement1, statement2)
1
2
ifelse(sorce>0.5, print("Passed"), print("Failed"))
outcome <- ifelse(socre>0.5, "Passed", "Failed")
  • switch结构:根据一个表达式的值选择语句执行switch(expr,...)
1
2
3
4
5
6
7
8
9
10
11
12
13
feelings <- c("sad", "afraid")
for (i in feelings)
print(
switch(i,
happy = "I am glad you are happpy", # 用逗号分隔
afraid = "There is nothing to fear",
sad = "Cheer Up",
angry = "Calm down now"
)
)
## expr之后的…是expr的可能取值,后接等号(=),表示执行的行为
## switch语句中,不同条件末尾要有 [逗号]
## 若expr为文本形式,输入时需加 [引号]


逻辑判断

  • which(): 返回为真的逻辑对象,允许对数组array使用


自编函数

  • 结构 : 用换行进行分割即可;注意同一范围内需要用大括号{}括起来
1
2
3
4
myfunction <- function(arg1, arg2, ...){
statements
return(object)
}


数据拆分

  • pretty(x, n) :将连续型变量x分给为n个区间
  • cut(x, n,[order_result=TRUE]):将连续型变量x分割成有n个水平的因子


应用

判断是否存在

  • is.element
  • %in%