使用complete()补全tibble后,如何填充缺失的文章名称字段?
问题:补全时间-商品组合数据时同步填充商品名称标签
我有一个长格式tibble数据集,包含不同日期下的商品销售数据,部分商品在某些日期无销售记录(缺失观测值)。为了绘制面积图(geom_area()会对缺失值取相邻均值,必须补全),我用complete()函数生成了所有日期与商品的组合,但补全后缺失记录对应的ArticleName(商品名称标签)为NA。商品ID与名称的映射关系存储在单独的tibble(articleData)中,希望用tidy的方式补全这个字段,要么在complete()时直接设置,要么事后填充。
模拟示例代码如下:
library(tidyverse) articleData = tibble(article = 1:3, description = c("Foo", "Bar", "Baz"), price = c(1, 2, 2)) article <- c(1:3, 1, 3, 1:3) description <- map_chr(article, ~ articleData[[., "description"]]) date <- as.Date(c(rep("2023-01-01", times = 3), rep("2023-01-02", times = 2), rep("2023-01-03", times = 3))) sales <- c(21, 58, 35, 32, 47, 25, 47, 42) price <- map_int(article, ~ articleData[[., "price"]]) data <- tibble( Date = date, Article = as_factor(article), ArticleName = description, Sales = sales, Price = price, Turnover = sales * price ) data %>% group_by(Date) %>% summarize( Date = unique(Date), TurnoverTotal = sum(Turnover), SalesTotal = sum(Sales) ) %>% full_join(data) %>% mutate( TurnoverShare = Turnover / TurnoverTotal, SalesShare = Sales / SalesTotal ) -> data # 补全缺失的日期-商品组合,填充占比为0,但ArticleName为NA data %>% complete( Date, Article, fill = list( SalesShare = 0, TurnoverShare = 0 ) ) -> data2
解决方案1:补全后通过左连接映射表填充
这是最直接的tidy处理方式,补全数据后,通过left_join()关联映射表articleData,根据Article字段匹配填充ArticleName,同时还能同步补全Price这类商品属性:
data2 <- data %>% complete(Date, Article, fill = list(SalesShare = 0, TurnoverShare = 0)) %>% # 将因子型的Article转换为数值,与articleData的article字段匹配 mutate(Article = as.integer(as.character(Article))) %>% # 左连接映射表,匹配商品名称和价格 left_join(articleData, by = c("Article" = "article")) %>% # 用映射表的description覆盖原NA的ArticleName rename(ArticleName = description) %>% # 按需将Article转回因子类型(绘图时保持分类变量属性) mutate(Article = as_factor(Article))
解决方案2:先生成完整组合再关联数据
如果希望从源头避免ArticleName缺失,可以先基于所有日期和所有商品生成完整的组合框架,再关联原始销售数据和映射表,最后填充缺失的数值字段:
data2 <- expand_grid( # 获取所有唯一日期和商品ID Date = unique(data$Date), Article = unique(data$Article) ) %>% # 关联原始销售数据 left_join(data, by = c("Date", "Article")) %>% # 关联商品映射表,直接获取名称和价格 left_join(articleData, by = c("Article" = "article")) %>% # 填充缺失的占比字段为0 mutate( SalesShare = replace_na(SalesShare, 0), TurnoverShare = replace_na(TurnoverShare, 0), # 用映射表的description赋值给ArticleName ArticleName = description ) %>% # 移除冗余的description字段 select(-description)
两种方法都能确保补全后的每条记录都有对应的ArticleName,后续可直接用glue()生成信息丰富的绘图标签,且不影响geom_area()的正常绘制。
内容的提问来源于stack exchange,提问作者BestGirl
相关产品推荐
相关产品推荐

