R语言基础5--tidyr包的函数及用法


R语言基础系列:

  • R语言基础1--R数据格式:.rds和.rda的区别
  • R语言基础2--数据排序与长宽型数据的转换
  • R语言基础3--tidyverse包总结
  • R语言基础4--dplyr包的函数及用法

tidyr包的应用
  • tidyr主要提供了一个类似Excel中数据透视表(pivot table)的功能。
  • gather()spread()函数将数据在长格式和宽格式之间相互转化,应用在比如稀疏矩阵和稠密矩阵之间的转化。(用于数据框 )
  • separate()union()方法提供了数据分组拆分、合并的功能,应用在nominal数据的转化上。(用于数据框 )
  • tidyr还提供一些简单的缺失值处理方法。
# 查看这个包的网页说明书
browseVignettes('tidyr')
1. gather实现wide 到 long 转换

类似reshape2包中melt函数的功能

  • 语法
gather(data, key = "key", value = "value",..., na.rm = FALSE, convert = FALSE, factor_key = FALSE)
  • 参数
参数 含义
data 需要被转换的宽形数据框
key 将原数据框中的所有列赋给一个新变量key
value 将原数据框中的所有值赋给一个新变量value
可以指定哪些列聚到同一列中,可用于选择两列之间的所有列col1:coln, 排除列-coln
na.rm 是否删除缺失值,默认为FALSE
convert 为TRUE时会自动在key列上使用type.convert函数,默认值为FALSE
factor_key FALSE时key值为字符向量,TRUE时key值为factor类型
  • 使用
library(tidyr)
library(dplyr)
stocks <- tibble(
  time = as.Date('2009-01-01') + 0:9,
  X = rnorm(10, 0, 1),
  Y = rnorm(10, 0, 2),
  Z = rnorm(10, 0, 4)
)
stocks
#  A tibble: 10 x 4
#    time             X      Y      Z
#               
 # 1 2009-01-01 -0.326   3.32   5.84 
#  2 2009-01-02  0.410   3.99  -1.97 
#  3 2009-01-03 -0.344  -0.394  4.09 
#  4 2009-01-04 -1.11    1.12  -5.43 
#  5 2009-01-05 -0.374   0.303  0.336
#  6 2009-01-06  2.72    1.38  -4.86 
#  7 2009-01-07  0.416   3.39  -1.27 
#  8 2009-01-08  2.31    1.25  -2.13 
#  9 2009-01-09 -0.0643  4.87   1.37 
# 10 2009-01-10 -0.0232  2.73   1.38 

gather(stocks, "stock", "price", -time)
stocks %>% gather("stock", "price", -time)
#  A tibble: 30 x 3
#    time       stock   price
#            
#  1 2009-01-01 X     -0.326 
#  2 2009-01-02 X      0.410 
#  3 2009-01-03 X     -0.344 
#  4 2009-01-04 X     -1.11  
#  5 2009-01-05 X     -0.374 
#  6 2009-01-06 X      2.72  
#  7 2009-01-07 X      0.416 
#  8 2009-01-08 X      2.31  
#  9 2009-01-09 X     -0.0643
# 10 2009-01-10 X     -0.0232
#  … with 20 more rows
2. spread实现long 到wide转换(类似reshape2包中cast函数的功能)
  • 语法
spread(data, key, value, fill = NA, convert = FALSE, drop = TRUE, sep = NULL)
  • 参数
参数 含义
data 为需要转换的长形data.frame
key 设置需要扩宽的类别变量
value 设置需要扩宽的变量的度量值
fill 对于缺失值,可将fill的值赋值给被转型后的缺失值
convert 为TRUE时会自动在新列上使用type.convert函数,其中as.is = TRUE,默认值为FALSE
drop 为FALSE保留factor的level,使用fill的值填充missing的值
sep 为默认值NULL时,新列名使用key中的值,非NULL时,新列名为
  • 使用
library(dplyr)
stocks <- data.frame(
  time = as.Date('2009-01-01') + 0:9,
  X = rnorm(10, 0, 1),
  Y = rnorm(10, 0, 2),
  Z = rnorm(10, 0, 4)
)
stocks
#  A tibble: 10 x 4
#    time             X      Y      Z
#               
 # 1 2009-01-01 -0.326   3.32   5.84 
#  2 2009-01-02  0.410   3.99  -1.97 
#  3 2009-01-03 -0.344  -0.394  4.09 
#  4 2009-01-04 -1.11    1.12  -5.43 
#  5 2009-01-05 -0.374   0.303  0.336
#  6 2009-01-06  2.72    1.38  -4.86 
#  7 2009-01-07  0.416   3.39  -1.27 
#  8 2009-01-08  2.31    1.25  -2.13 
#  9 2009-01-09 -0.0643  4.87   1.37 
# 10 2009-01-10 -0.0232  2.73   1.38 

stocksm <- stocks %>% gather(stock, price, -time)
head(stocksm)
#         time stock      price
# 1 2009-01-01     X  0.8126651
# 2 2009-01-02     X -0.3387208
# 3 2009-01-03     X -0.6778238
# 4 2009-01-04     X  0.3713640
# 5 2009-01-05     X -1.5019406
# 6 2009-01-06     X -0.8858434

stocksm %>% spread(stock, price)
#          time           X           Y           Z
# 1  2009-01-01  0.81266513 -2.21316283   7.9265756
# 2  2009-01-02 -0.33872080  3.52921094  -1.2218472
# 3  2009-01-03 -0.67782385 -1.82005963   1.2567876
# 4  2009-01-04  0.37136402 -1.22181178  -0.2963697
# 5  2009-01-05 -1.50194061 -1.56952607   3.1274926
# 6  2009-01-06 -0.88584341  5.17005476 -10.9974695
# 7  2009-01-07  0.22308469  0.07021010  -3.2228298
# 8  2009-01-08  0.08303945 -5.20103460  -0.1731917
# 9  2009-01-09 -0.58188891 -0.47327216   0.7320103
# 10 2009-01-10 -0.33931690  0.01911578  -7.2114319
stocksm %>% spread(time, price)
#   stock 2009-01-01 2009-01-02 2009-01-03 2009-01-04 2009-01-05  2009-01-06
# 1     X  0.8126651 -0.3387208 -0.6778238  0.3713640  -1.501941  -0.8858434
# 2     Y -2.2131628  3.5292109 -1.8200596 -1.2218118  -1.569526   5.1700548
# 3     Z  7.9265756 -1.2218472  1.2567876 -0.2963697   3.127493 -10.9974695
#   2009-01-07  2009-01-08 2009-01-09  2009-01-10
# 1  0.2230847  0.08303945 -0.5818889 -0.33931690
# 2  0.0702101 -5.20103460 -0.4732722  0.01911578
# 3 -3.2228298 -0.17319172  0.7320103 -7.21143190
3. unite 可将多列按指定分隔符合并为一列
  • 语法
unite(data, col, ..., sep = "_", remove = TRUE)
  • 参数
参数 含义
data 为数据框
col 被组合的新列名称
指定哪些列需要被组合, 可用于选择两列之间的所有列col1:coln, 排除列-coln
sep 组合列之间的连接符,默认为下划线
remove 是否删除被组合的列
  • 使用
df <- expand_grid(x = c("a", NA), y = c("b", NA))
df
#   A tibble: 4 x 2
#   x     y    
#    
# 1 a     b    
# 2 a     NA   
# 3 NA    b    
# 4 NA    NA 

df %>% unite("z", x:y, remove = FALSE) #若remove = TRUE,则不保留x和y列
#   A tibble: 4 x 3
#   z     x     y    
#    
# 1 a_b   a     b    
# 2 a_NA  a     NA   
# 3 NA_b  NA    b    
# 4 NA_NA NA    NA 

df %>% unite("z", x:y, na.rm = TRUE, remove = FALSE)
#   A tibble: 4 x 3
#   z     x     y    
#     
# 1 "a_b" a     b    
# 2 "a"   a     NA   
# 3 "b"   NA    b    
# 4 ""    NA    NA 
4. separate分割一列为多列

类似于reshape2中的colsplit函数

  • 语法
separate(data, col, into, sep = "[^[:alnum:]]+", remove = TRUE, convert = FALSE, extra = "warn", fill = "warn", ...)
  • 参数
参数 含义
data 为数据框
col 需要被拆分的列
into 新建的列名,为字符串向量
sep 被拆分列的分隔符
remove 是否删除被分割的列
convert 为TRUE时会自动在新列上使用type.convert函数,其中as.is = TRUE,默认值为FALSE
extra 当分割成的列多于length(into)时,"warn"(默认值) 发出警告并删除多余值,"drop"直接删除多余值,"merge"仅分割length(into)次
fill 当分割成的列少于length(into)时,"warn"(默认值) 发出警告并从右侧填充缺失值,"right"直接从右侧填充缺失值,"left"直接从左侧填充缺失值
  • 使用
library(dplyr)
df <- data.frame(x = c(NA, "a.b", "a.d", "b.c"))
#分割为两列,保留NA值
df %>% separate(x, c("A", "B"))
df <- data.frame(x = c("a", "a b", "a b c", NA))
#分割为两列,发出warning并删除多余的列,缺失的列从右以NA填充
df %>% separate(x, c("a", "b"))
#分割为两列,直接删除多余的列,缺失的列从右以NA填充
df %>% separate(x, c("a", "b"), extra = "drop", fill = "right")
#分割两次(设置的列为两列),缺失的列从左以NA填充
df %>% separate(x, c("a", "b"), extra = "merge", fill = "left")
df <- data.frame(date = c("2017-03-08 01:20:20", "2017-03-09 02:30:30", "2017-03-10 03:40:40"))
#分割为year,month,day,hour,minute,second六列
df %>% 
  separate(date, c("day", "time"), sep = " ") %>%
  separate(day, c("year", "month", "day"), sep = "-") %>% 
  separate(time, c("hour", "minute", "second"), sep = ":") 

与separate不同的是extract使用正则表达式regex提取需要分割的列,当输入为NA或者不能匹配regex时,输出为NA。

extract(data, col, into, regex = "([[:alnum:]]+)", remove = TRUE, convert = FALSE, ...)
library(dplyr)
df <- data.frame(x = c(NA, "a.b", "a.d", "b.c"))
#分割为两列,regex匹配要分割的列
df %>% extract(x, c("a", "b"), regex = "([a-d]+).([a-d]+)")
df %>% extract(x, c("A", "B"), "([[:alnum:]]+).([[:alnum:]]+)")
#分割为两列,regex匹配要分割的列,不能匹配列的输出为NA
df %>% extract(x, c("a", "b"), regex = "([a-d]+).([a-c]+)")
#分割为一列
df %>% extract(x, c("a"), regex = "([a-d]+)")
df %>% extract(x, c("a"))

separate_rows用于将列分割为多行,”... ”用于设置需要分割的列,sep用于设置分隔符,需要注意的是分割多个列时,每个列分割成的行数必须要一致。

separate_rows(data, ..., sep = "[^[:alnum:].]+", convert = FALSE)
library(dplyr)
df <- data.frame(
  x = 1:3,
  y = c("a", "d,e,f", "g,h"),
  z = c("1", "2,3,4", "5,6"),
  stringsAsFactors = FALSE
)
#分割y和z列,转换为行
separate_rows(df, y, z, convert = TRUE)
5. 缺失值处理

tidyr包提供了简单的缺失值处理方法,包括替换,填充,删除等

  • 使用给定值替换每列的缺失值
replace_na(data, replace = list(), ...)
# data:为数据框
# replace:替换值用于替换每个列中NA
library(dplyr)
df <- tibble(x = c(1, 2, NA), y = c("a", NA, "b"))
#以0替换x中的NA,以unknown替换y中的NA
df %>% replace_na(list(x = 0, y = "unknown"))
  • 以前一个值填充缺失值,默认自上向下填充
fill(data, ..., .direction = c("down", "up"))
# data:为数据框
# …:指定需要被填充的列, 可用于选择两列之间的所有列col1:coln, 排除列-coln
# .direction :填充的方向,默认为down,自上向下填充
df <- data.frame(x = 1:5, y = c(10, NA, 15, NA, 20))
#自上向下替换NA值
df %>% fill(y)
df %>% fill(y, .direction = "down")
#自下向上替换NA值
df %>% fill(y, .direction = "up")
  • 填充以创建完整的序列值向量
full_seq(x, period, tol = 1e-06)
# x:数值向量
# period:观测值间的间隔,并检测现有数据是否与这个间隔匹配,,不匹配时报错
#返回序列1:6
full_seq(c(1, 2, 4, 6), 1)
#period值与原数据间隔不匹配,报错Error: `x` is not a regular sequence.
full_seq(c(1, 2, 4, 6), 2)
#返回序列1:13,间隔为2
full_seq(c(1, 5, 9, 13), 2)
  • 删除包含缺失值的行
drop_na(data, ...)
# data:为数据框
# …:指定需要被填充的列, 可用于选择两列之间的所有列col1:coln, 排除列-coln
df <- data_frame(x = c(1, 2, NA), y = c("a", NA, "b"))
#删除变量x中NA对应的行
df %>% drop_na(x)
#删除变量y中NA对应的行
df %>% drop_na(y)
#未设置列,删除变量x和y中NA对应的行
df %>% drop_na()
  • 转换隐式的缺失值为显式的
complete(data, ..., fill = list())
# data:为数据框
# …:指定需要扩展的列,每个输入列都作为一个独立的参数用于扩展数据框。其中使用crossing或者直接输入列作为参数时,会使用每个列中的元素进行扩展,即使生成的组合在原数据框中不存在;而使用nesting函数时,返回的每个列元素的组合必须在原数据框中存在。
# fill:用于设置填充值以替换NA
df <- data_frame(
  group = c(1:2, 1),
  item_id = c(1:2, 2),
  item_name = c("a", "b", "b"),
  value1 = 1:3,
  value2 = 4:6
)
#以item_id和item_name中的每个元素扩展原数据框, 组合后的缺失值以NA代替
df %>% complete(item_id, item_name)
df %>% complete(crossing(item_id, item_name))
#以item_id和item_name中的每个元素扩展原数据框, 并以给定值替换缺失值
df %>% complete(item_id, item_name, fill = list(group = 0, value1 = 0, value2 = 0))
#以item_id和item_name中的每个元素扩展原数据框,只返回原数据框中存在的组合
df %>% complete(nesting(item_id, item_name))
 
#保留group,以item_id和item_name中的每个元素扩展原数据框,只返回原数据框
#中item_id和item_name存在的组合
df %>% complete(group, nesting(item_id, item_name))
df %>% complete(group, nesting(item_id, item_name), fill = list(value1 = 0, value2 = 0))
 
#保留group,以item_id和item_name中的每个元素扩展原数据框,返回所有item_id
#和item_name存在的组合
df %>% complete(group, crossing(item_id, item_name))
df %>% complete(group, crossing(item_id, item_name), fill = list(value1 = 0, value2 = 0))

参考:https://blog.csdn.net/wltom1985/article/details/107902563

你可能感兴趣的:(R语言基础5--tidyr包的函数及用法)