tidyr学习笔记一:用fill和complete处理缺失值NA
tidyr学习笔记一:用fill和complete处理缺失值NA
一、complete函数
complete函数用来把隐式的缺失值转换成正常显示的缺失值。
#A tibble: 7 x 3
year qtr return
<dbl> <dbl> <dbl>
1 2015 1 1.88`
2 2015 2 0.59`
3 2015 3 0.35`
4 2015 4 NA
5 2016 2 0.92
6 2016 3 0.17
7 2016 4 2.66
在日常的数据透视中,会经常遇到经计算后,由于某些组别为0,出现若干隐式缺失值的情况。
例如上表中,2015年第四季度的return值为正常显示的显式缺失值,而2016年第一季度的return值则直接未在表中出现,为隐式缺失值。
函数用法:
complete(data, ..., fill = list())
complete包含三大参数,分别为
data,操作的数据框;
... 需要完善的变量名,显然,可以传入不止一个变量,达到一次补充多个变量缺失的目的,如果指定的变量为因子变量,默认将会把所有缺失的分类都补回数据中,如果只想补充数据中出现过的分类,那么需要将其去因子化后再进行操作;
fill = list(),如果不想用NA填充补充上隐式缺失值,可以通过fill传入一个列表,如果有多个变量,那每个变量可以分别指定一个值来代替NA。
帮助文档中的例子:
df <- tibble(
group = c(1:2, 1),
item_id = c(1:2, 2),
item_name = c("a", "b", "b"),
value1 = 1:3,
value2 = 4:6
)
# A tibble: 3 x 5
group item_id item_name value1 value2
<dbl> <dbl> <chr> <int> <int>
1 1 1 a 1 4
2 2 2 b 2 5
3 1 2 b 3 6
构造一个tibble,显然,这个tibble的group,item_id和item_name分组都是存在缺失的。
df %>% complete(group, nesting(item_id, item_name))
# A tibble: 4 x 5
group item_id item_name value1 value2
<dbl> <dbl> <chr> <int> <int>
1 1 1 a 1 4
2 1 2 b 3 6
3 2 1 a NA NA
4 2 2 b 2 5
用complete处理后,缺失的分组都被补了回去,这里用 nesting(item_id, item_name) 是因为item_id和item_name其实是一一对应关系,1和a、2和b是成对的,如果不是成对关系,可以直接写成:
df %>% complete(group,item_id, item_name)
# A tibble: 8 x 5
group item_id item_name value1 value2
<dbl> <dbl> <chr> <int> <int>
1 1 1 a 1 4
2 1 1 b NA NA
3 1 2 a NA NA
4 1 2 b 3 6
5 2 1 a NA NA
6 2 1 b NA NA
7 2 2 a NA NA
8 2 2 b 2 5
当然可以用fill来指定某个值来替代NA来填充补充上来的数据。
df %>% complete(group, nesting(item_id, item_name), fill = list(value1 = 0))
# A tibble: 4 x 5
group item_id item_name value1 value2
<dbl> <dbl> <chr> <dbl> <int>
1 1 1 a 1 4
2 1 2 b 3 6
3 2 1 a 0 NA
4 2 2 b 2 5
变量为因子变量时:
df <- tibble(sex = c(rep('男',4),rep('女',2)),age=c('0~','15~','55~','85~','5~','10~'),pop = c(4,2,1,3,10,4))
# A tibble: 6 x 3
sex age pop
<chr> <chr> <dbl>
1 男 0~ 4
2 男 15~ 2
3 男 55~ 1
4 男 85~ 3
5 女 5~ 10
6 女 10~ 4
构造一个透视过的数据,我们需要的是年龄分成19组的数据,但是其他分组由于数据为0都被隐去了,把age转换成因子变量再用complete操作补回就变得非常简单。
labels19 <- c('0~','1~','5~','10~','15~','20~','25~','30~','35~',
'40~','45~','50~','55~','60~','65~','70~','75~','80~','85~')
df %>% mutate(age = factor(age,levels = labels19)) %>%
complete(age,sex,fill = list(pop = 0))
# A tibble: 38 x 3
age sex pop
<fct> <chr> <dbl>
1 0~ 男 4
2 0~ 女 0
3 1~ 男 0
4 1~ 女 0
5 5~ 男 0
6 5~ 女 10
7 10~ 男 0
8 10~ 女 4
9 15~ 男 2
10 15~ 女 0
# ... with 28 more rows
二、fill函数
fill函数可以将选中变量列的缺失值填充完整,可以选择从上往下填充或者从下往上填充,这个函数非常契合因变量数据因重复而被省略仅有变化时才输入的场景。
参数
data 被操作的数据框;
... 变量列,与complete一样,可以传入多个变量列进行操作;
direction 默认值为down,即从上向下填充,其他的值还有up,downup(先向下再向上),updown(先向上再向下。
帮助文档中的例子:
sales <- tibble::tribble(
~quarter, ~year, ~sales,
"Q1", 2000, 66013,
"Q2", NA, 69182,
"Q3", NA, 53175,
"Q4", NA, 21001,
"Q1", 2001, 46036,
"Q2", NA, 58842,
"Q3", NA, 44568,
"Q4", NA, 50197,
"Q1", 2002, 39113,
"Q2", NA, 41668,
"Q3", NA, 30144,
"Q4", NA, 52897,
"Q1", 2004, 32129,
"Q2", NA, 67686,
"Q3", NA, 31768,
"Q4", NA, 49094
)
# A tibble: 16 x 3
quarter year sales
<chr> <dbl> <dbl>
1 Q1 2000 66013
2 Q2 NA 69182
3 Q3 NA 53175
4 Q4 NA 21001
5 Q1 2001 46036
6 Q2 NA 58842
7 Q3 NA 44568
8 Q4 NA 50197
9 Q1 2002 39113
10 Q2 NA 41668
11 Q3 NA 30144
12 Q4 NA 52897
13 Q1 2004 32129
14 Q2 NA 67686
15 Q3 NA 31768
16 Q4 NA 49094
用fill操作后,默认向下填充
sales %>% fill(year)
# A tibble: 16 x 3
quarter year sales
<chr> <dbl> <dbl>
1 Q1 2000 66013
2 Q2 2000 69182
3 Q3 2000 53175
4 Q4 2000 21001
5 Q1 2001 46036
6 Q2 2001 58842
7 Q3 2001 44568
8 Q4 2001 50197
9 Q1 2002 39113
10 Q2 2002 41668
11 Q3 2002 30144
12 Q4 2002 52897
13 Q1 2004 32129
14 Q2 2004 67686
15 Q3 2004 31768
16 Q4 2004 49094
squirrels <- tibble::tribble(
~group, ~name, ~role, ~n_squirrels,
1, "Sam", "Observer", NA,
1, "Mara", "Scorekeeper", 8,
1, "Jesse", "Observer", NA,
1, "Tom", "Observer", NA,
2, "Mike", "Observer", NA,
2, "Rachael", "Observer", NA,
2, "Sydekea", "Scorekeeper", 14,
2, "Gabriela", "Observer", NA,
3, "Derrick", "Observer", NA,
3, "Kara", "Scorekeeper", 9,
3, "Emily", "Observer", NA,
3, "Danielle", "Observer", NA
)
# A tibble: 12 x 4
group name role n_squirrels
<dbl> <chr> <chr> <dbl>
1 1 Sam Observer NA
2 1 Mara Scorekeeper 8
3 1 Jesse Observer NA
4 1 Tom Observer NA
5 2 Mike Observer NA
6 2 Rachael Observer NA
7 2 Sydekea Scorekeeper 14
8 2 Gabriela Observer NA
9 3 Derrick Observer NA
10 3 Kara Scorekeeper 9
11 3 Emily Observer NA
12 3 Danielle Observer NA
squirrels %>%
dplyr::group_by(group) %>%
fill(n_squirrels, .direction = "downup") %>%
dplyr::ungroup()
# A tibble: 12 x 4
group name role n_squirrels
<dbl> <chr> <chr> <dbl>
1 1 Sam Observer 8
2 1 Mara Scorekeeper 8
3 1 Jesse Observer 8
4 1 Tom Observer 8
5 2 Mike Observer 14