R Tidyverse : Carry forward values for non existing variables

标签 r tidyverse fill forward

我确实有一个问题,我似乎无法有效地解决。

假设我的循环结果如下(编造的)。

library(tidyverse)
  mytib <- tribble(
  ~year,  ~month, ~shop_id, ~inventory,
  2019, 01, "A", 200,
  2019, 01, "B", 300,
  2019, 01, "C", 240,
  2019, 05, "A", 250,
  2019, 05, "B", 400,
  2019, 05, "D", 400,
  2019, 08, "A", 300,
  2019, 08, "B", 250,
  2019, 08, "C", 200,
  2019, 11, "A", 300,
  2019, 11, "E", 250,)

也就是说,我只获得一月、五月、八月和十一月的结果(因为只有这些日期的数据可用)。但是,我想将二月、三月、六月的值向前推进(这些值将获得一月的值。六月和七月将获得五月的值,依此类推。我不能使用“填充”,因为 R 不“知道”有二月、三月……等等(我不能将这些月份“变异”为“mytib”。)

不幸的是,我提出了一个非常低效且容易出错的解决方案。解决方案(用文字)如下:创建一个网格,包含从 1:12 开始的月份和所有唯一的 shop_id(见下面的代码),然后用我在 1 月、5 月、8 月和 11 月观察到的商店创建单独的向量。

然后按月和年对网格进行 group_split(成列表)。然后将所有独特的 shopid 减少到我观察到的那些。将它们全部加入(使用 dplyr::join_all),然后将原始 tibble 左连接到减少的网格,最后进行(.direction="down")观察到的值,这样我就得到了一个 tibbe“结果”,这就是我想要的。

虽然我达到了我想要的目标,但我想知道是否有比我笨手笨脚的方法更有效且更不容易出错的解决方案。非常感谢任何帮助或提示。

附言。请不要对我太苛刻,因为我对 R 还是很陌生。

完整代码如下:

mytib <- tribble(
  ~year,  ~month, ~shop_id, ~inventory,
  2019, 01, "A", 200,
  2019, 01, "B", 300,
  2019, 01, "C", 240,
  2019, 05, "A", 250,
  2019, 05, "B", 400,
  2019, 05, "D", 400,
  2019, 08, "A", 300,
  2019, 08, "B", 250,
  2019, 08, "C", 200,
  2019, 11, "A", 300,
  2019, 11, "E", 250,)


grid <- expand.grid(year = 2019, 
                    month = 1:12, 
                   shop_id = unique(mytib$shop_id))


grid

jan2019 <- mytib %>% filter(year == 2019 & month ==01)
jan2019 <- jan2019$shop_id

may2019 <- mytib %>% filter(year == 2019 & month == 05)
may2019 <- may2019$shop_id

aug2019 <- mytib %>% filter(year == 2019 & month == 08)
aug2019  <-aug2019$shop_id

nov2019 <- mytib %>% filter(year == 2019 & month == 11)
nov2019 <- nov2019$shop_id


my_list <- grid %>% group_by(year, month) %>% group_split()
my_list



my_list[[1]] <- my_list[[1]][my_list[[1]]$shop_id %in% jan2019,] ; my_list[[1]]
my_list[[2]] <- my_list[[2]][my_list[[2]]$shop_id %in% jan2019,] ; my_list[[2]]
my_list[[3]] <- my_list[[3]][my_list[[3]]$shop_id %in% jan2019,] ; my_list[[3]]
my_list[[4]] <- my_list[[4]][my_list[[4]]$shop_id %in% jan2019,] ; my_list[[4]]
my_list[[5]] <- my_list[[5]][my_list[[5]]$shop_id %in% may2019,] ; my_list[[5]]
my_list[[6]] <- my_list[[6]][my_list[[6]]$shop_id %in% may2019,] ; my_list[[6]]
my_list[[7]] <- my_list[[7]][my_list[[7]]$shop_id %in% may2019,] ; my_list[[7]]
my_list[[8]] <- my_list[[8]][my_list[[8]]$shop_id %in% aug2019,] ; my_list[[8]]
my_list[[9]] <- my_list[[9]][my_list[[9]]$shop_id %in% aug2019,] ; my_list[[9]]
my_list[[10]]<- my_list[[10]][my_list[[10]]$shop_id %in% aug2019,];my_list[[10]]
my_list[[11]]<- my_list[[11]][my_list[[11]]$shop_id %in% nov2019,];my_list[[11]]
my_list[[12]]<- my_list[[12]][my_list[[12]]$shop_id %in% nov2019,];my_list[[12]]

result <- plyr::join_all(my_list, type="full")
result
result <- left_join(result, mytib, by=c("year", "month", "shop_id"))
result %>% group_by(shop_id) %>% fill(inventory,.direction =  "down") %>% print(n=35)

最佳答案

您的代码很好,可能值得重写,因为您知道每个函数的作用,因为我使用的基本函数都包含在您的代码中。要将结果添加到所有数据中的缺失值,我们可以使用 left_joinright_join 函数,它们都能够匹配某些值并维护第一个中的所有条目或第二个参数。

在此之后,我们按 shop_id 分组,因为我们想为每个商店分别填写值。然后我们使用 tidyr::fill() 填写值,指定我们要填写向下方向(即升序日期)。最后,我们使用过滤器删除 NA 结果。

library(tidyverse)


mytib <- tribble(
  ~year,  ~month, ~shop_id, ~inventory,
  2019, 01, "A", 200,
  2019, 01, "B", 300,
  2019, 01, "C", 240,
  2019, 05, "A", 250,
  2019, 05, "B", 400,
  2019, 05, "D", 400,
  2019, 08, "A", 300,
  2019, 08, "B", 250,
  2019, 08, "C", 200,
  2019, 11, "A", 300,
  2019, 11, "E", 250,)


grid <- expand.grid(year = 2019, 
                    month = 1:12, 
                    shop_id = unique(mytib$shop_id))

left_join(grid, mytib, by = c("year" = "year", "month" = "month", "shop_id" = "shop_id")) %>%
  group_by(shop_id) %>% 
  fill(inventory, .direction = "down") %>% 
  filter(!is.na(inventory))
#> # A tibble: 46 x 4
#> # Groups:   shop_id [5]
#>     year month shop_id inventory
#>    <dbl> <dbl> <chr>       <dbl>
#>  1  2019     1 A             200
#>  2  2019     2 A             200
#>  3  2019     3 A             200
#>  4  2019     4 A             200
#>  5  2019     5 A             250
#>  6  2019     6 A             250
#>  7  2019     7 A             250
#>  8  2019     8 A             300
#>  9  2019     9 A             300
#> 10  2019    10 A             300
#> # ... with 36 more rows

reprex package 创建于 2021-04-07 (v2.0.0)

关于R Tidyverse : Carry forward values for non existing variables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66989760/

相关文章:

r - 如何在 data.table 中通过参数设置名称?

r - 如何在数据表的每一行上有效地应用可归约函数

R:下标文本作为变量

R read_excel 或 readxl 具有多个工作表的多个文件 - 绑定(bind)

r - 在r中使用atop函数时获得恒定的文本大小

R,按组递归地将文本从一行添加到另一行

javascript - 如何根据动态变化的百分比值为图像着色?

r - 如何从 R 中的统一列表中提取值?

css - 更改 SVG 的颜色

c# - 什么是C# 等同于C++ STL 填充方法