我想填充不是基于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()
,那些就会被填满。
如果有人能帮我解决上述两个问题,我将不胜感激。
答案 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