根据组中的可用值填充缺失值

时间:2017-02-02 08:53:02

标签: r dplyr tidyr

我想填充不是基于LOCF的缺失值,而是基于该组可用的值。虽然我能够根据Filling missing value in group的答案做到这一点,但我正在寻找有关以下内容的解释:

问题a) (Final_Rank = Final_Rank[1])。海报没有解释这一部分。

问题b)还有其他更高效(速度方面)的方法吗?我看到一个使用Data.Table,但我不太熟悉它。我无法使用Data.Table执行此操作。实际数据大小为2GB。

以下是我的数据:

dput(DF)
structure(list(SL3 = c("SE", "SE", "SE", "SE", "SE", "SE", "SW", 
"SW", "SW", "SW", "SW", "SW"), SL6 = c("SL123", "SL123", "SL123", 
"SL123", "SL123", "SL124", "SL123", "SL123", "SL123", "SL123", 
"SL123", "SL124"), Sname = c("123 Inc", "123 Inc", "123 Inc", 
"123 Inc", "123 Inc", "234 Inc", "345 Inc", "345 Inc", "345 Inc", 
"345 Inc", "345 Inc", "567 Inc"), Group = c("Red", "Sapphire", 
"Red", "Sapphire", "White", "Red", "Red", "Sapphire", "Red", 
"Sapphire", "White", "Red"), Final_Rank = c("High", "Medium", 
NA, NA, "Low", NA, "High", "Medium", NA, NA, "Low", NA), Value = c(1, 
2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6)), .Names = c("SL3", "SL6", "Sname", 
"Group", "Final_Rank", "Value"), row.names = c(NA, 12L), class = "data.frame")

这是我的代码:

DF%>% 
  dplyr::group_by(SL3,SL6, Sname, Group) %>%
  dplyr::arrange(SL3,SL6, Sname, Group, Final_Rank) %>%
  dplyr::mutate(Final_Rank = Final_Rank[1])

预期输出:

     SL3   SL6   Sname    Group Final_Rank Value
   <chr> <chr>   <chr>    <chr>      <chr> <dbl>
1     SE SL123 123 Inc      Red       High     1
2     SE SL123 123 Inc      Red       High     3
3     SE SL123 123 Inc Sapphire     Medium     2
4     SE SL123 123 Inc Sapphire     Medium     4
5     SE SL123 123 Inc    White        Low     5
6     SE SL124 234 Inc      Red       <NA>     6
7     SW SL123 345 Inc      Red       High     1
8     SW SL123 345 Inc      Red       High     3
9     SW SL123 345 Inc Sapphire     Medium     2
10    SW SL123 345 Inc Sapphire     Medium     4
11    SW SL123 345 Inc    White        Low     5
12    SW SL124 567 Inc      Red       <NA>     6

正如我们上面所看到的,因为第12行和第6行的其他地方都没有Final_Rank,我会得到NA。如果我使用tidyr::fill(),那些就会被填满。

如果有人能帮我解决上述两个问题,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

对于A部分,这里是@ Haboryme的评论(保留在答案中):

  

Final_Rank = Final_Rank[1]只需将Final_Rank替换为Final_Rank的第一个值。如果有非NA,它将是第一个。 - Haboryme

要进行扩展,使用group_by时,它会在组中选择Final_Rank 的第一个条目。这只是首先因为您在代码中arrange Final_Rank。您可以将Final_Rank[1]替换为任何选定的值,包括常量(例如"Missing")或计算值(例如,paste(Final_Rank %>% unique %>% sort, sep ="; ")以连接该组中的所有值)。

只是看时间,所描述的mutate方法已经相当不错了。 data.table解决方案往往会快一点,但我发现语法很难,因为我在编程/调试(然后是一些)中丢失了在运行时刮掉的时间,除非我运行代码很多

以下是当前microbenchmark解决方案的快速基准(使用mutate包),建议的fill解决方案以及生成&#34;查找表的解决方案&# 34;使用所需的条目,然后将其重新加入。请注意,如果有多个有效的fill条目,Final_Rank将给出与其他答案不同的答案。

library(microbenchmark)

microbenchmark(
  mutate =
    DF%>% 
    group_by(SL3,SL6, Sname, Group) %>%
    arrange(SL3,SL6, Sname, Group, Final_Rank) %>%
    mutate(Final_Rank = ifelse(is.na(Final_Rank), Final_Rank[1], Final_Rank))
  , fill =
    DF%>% 
    group_by(SL3,SL6, Sname, Group) %>%
    arrange(SL3,SL6, Sname, Group, Final_Rank) %>%
    fill(Final_Rank)
  , left_join =
    DF%>% 
    select(-Value) %>%
    group_by(SL3,SL6, Sname, Group) %>%
    arrange(Final_Rank) %>%
    slice(1) %>%
    rename(newRank = Final_Rank) %>%
    left_join(DF, .) %>%
    arrange(SL3,SL6, Sname, Group)

)

给出

Unit: milliseconds
      expr      min       lq     mean   median       uq      max neval
    mutate 1.783668 1.848683 1.954992 1.904577 1.968923 3.093098   100
      fill 3.299220 3.399997 3.558219 3.491215 3.573784 4.756986   100
 left_join 3.097166 3.214982 3.379452 3.300272 3.420206 4.653970   100

请注意,mutate解决方案比其他两个解决方案快一点,但可能存在其他解决方案(如果组大小增加,这些解决方案可能会有不同的扩展)。

最后,请注意,当前实现将Final_Rank中的 ALL 条目替换为组中的第一个条目。如果您只想替换缺少的条目,则需要使用ifelse(或fill,如上所述),如下所示:

DF%>% 
  group_by(SL3,SL6, Sname, Group) %>%
  arrange(SL3,SL6, Sname, Group, Final_Rank) %>%
  mutate(Final_Rank = ifelse(is.na(Final_Rank), Final_Rank[1], Final_Rank))

我将其添加到microbenchmark并且它似乎并没有显着减缓:

Unit: milliseconds
      expr      min       lq     mean   median       uq      max neval
    mutate 1.752267 1.835038 1.937181 1.900086 1.946848 3.197292   100
      fill 3.289838 3.414916 3.626607 3.507186 3.618336 5.857506   100
 left_join 3.052692 3.209808 3.371702 3.260593 3.377899 6.924646   100
    ifelse 1.771460 1.813426 1.935845 1.883497 1.951977 3.113328   100