也谈R语言的嵌套和还原
所谓的嵌套函数可用于将指定列的对应元素‘折叠’为list,缩小原有数据框的大小。Tidyr提供两个函数进行嵌套合并操作,nest()将分组数据框转换为嵌套数据框,即包含列表列的数据框,转换后分组列只会保留每个值的唯一值,与之对应合并列中的所有值会合并为list对象生成新列,这里需要注意的是所有合并列都会合并在一起生成一列,chop()函数稍微有些区别,合并列会分别进行合并,而不是全部整合在一起。#所有合并列全部一起nest为新列nest(.data, ..., .key = deprecated())#合并列分别进行nestchop(data, cols)# 将除Species的列进行nest操作,生成的新列的元素都为list对象# 其中nest()合并为一列,chop()分别对各列进行合并iris %>% nest(data = -Species)iris %>% chop(cols = -Species)nest_vars <- names(iris)[1:4]iris %>% nest(data = one_of(nest_vars))iris %>% chop(cols = one_of(nest_vars))# 分别组合多列进行合并,chop()不支持此操作iris %>% nest(petal = starts_with("Petal"), sepal = starts_with("Sepal"))# 先进行分组操作,分组变量之外的变量会进行nest合并iris %>% group_by(Species) %>% nest()# 对不同分组建立线性模型mtcars %>%group_by(cyl) %>%nest() %>%mutate(models = lapply(data, function(df) lm(mpg ~ wt, data = df)))与之相反,unnest()函数和unchop()可以进行数据框展开,把折叠的list对象展开。#unnest数据框对象unnest(data, cols, ..., keep_empty = FALSE, ptype = NULL,names_sep = NULL, names_repair = "check_unique",.drop = deprecated(), .id = deprecated(), .sep = deprecated(),.preserve = deprecated())unchop(data, cols, keep_empty = FALSE, ptype = NULL)df <- tibble(x = 1:4,y = list(NULL, 1:2, 3, NULL),z = list('d', c('a', "b"), "c", NULL))# 展开y和z列,并且删除值都为NULL的行,不全为NULL的行保留df %>% unnest(c(y, z))df %>% unchop(c(y, z))# 展开y和z列,设置keep_empty = TRUE保留所有行df %>% unnest(c(y, z), keep_empty = TRUE)df %>% unchop(c(y, z), keep_empty = TRUE)# 展开y和z列,设置展开后列的类型df %>% unchop(c(y, z), ptype = tibble(y = character(), z = character()))# 先使用y列展开,在使用z展开,和直接使用y,z展开不同,y和z会进行笛卡尔积df %>% unchop(y) %>% unchop(z)6. 缺失值处理tidyr包提供了简单的缺失值处理方法,包括替换,填充,删除等。#使用给定值替换每列的缺失值replace_na(data, replace = list(), ...)data:为数据框replace:替换值用于替换每个列中NAlibrary(dplyr)df <- tibble(x = c(1, 2, NA), y = c("a", NA, "b"))#以0替换x中的NA,以unknown替换y中的NAdf %>% 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:6full_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,间隔为2full_seq(c(1, 5, 9, 13), 2)#删除包含缺失值的行drop_na(data, ...)data:为数据框…:指定需要被填充的列, 可用于选择两列之间的所有列col1:coln, 排除列-colndf <- 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:用于设置填充值以替换NAdf <- 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))