簡體   English   中英

如何在R中使用dplyr運行有效的group_by語句

[英]How to run efficient group_by statement using dplyr in R

我有一個包含多個重復ID的數據集,這些ID具有不同的分類值。 以下是示例數據集。

suppressMessages(library(dplyr))
DUMMY_DATA <- data.frame(ID = c(11,22,22,33,33,33,44,44,55,55,55,55),
                     CATEGORY1 = c("E","B","C","C","C","D","A","A","B","C","E","B"),
                     CATEGORY2 = c ("AA","AA","BB","CC","DD","BB","AA","EE","AA","CC","BB","EE"),
                     stringsAsFactors = FALSE)

> DUMMY_DATA
   ID CATEGORY1 CATEGORY2
1  11         E        AA
2  22         B        AA
3  22         C        BB
4  33         C        CC
5  33         C        DD
6  33         D        BB
7  44         A        AA
8  44         A        EE
9  55         B        AA
10 55         C        CC
11 55         E        BB
12 55         B        EE

我想從另一個給出分類值等級的數據集中聚合ID值。 如下。

Category_Rank1 <- data.frame(VAR = c("A","B","C","D","E"),
                        RANK = c(1,2,3,4,5),stringsAsFactors = FALSE
)
> Category_Rank1
  VAR RANK
1   A    1
2   B    2
3   C    3
4   D    4
5   E    5

Category_Rank2 <- data.frame(VAR = c("AA","BB","CC","DD","EE"),
                            RANK = c(1,2,3,4,5),stringsAsFactors = FALSE
)

> Category_Rank2
  VAR RANK
1  AA    1
2  BB    2
3  CC    3
4  DD    4
5  EE    5

對於DUMMY_DAT中的每個ID組,我要查找Category_Rank,然后將該類別分配給具有最佳排名的ID。 以下是我的解決方案。

hierarchyTransform <- function(x,dataset){
  x <- unique(x)
  dataset <- dataset%>%
    filter(dataset[,1] %in% x)
  dataset <- dataset%>%
    filter(dataset[,2] == min(dataset[,2]))
  return(dataset[1,1])
}


NEW_DATA <- DUMMY_DATA%>%
          group_by(ID)%>%
          summarise(CATEGORY1_CLEAN = hierarchyTransform(x=CATEGORY1,
                                                         dataset = Category_Rank1),
                    CATEGORY2_CLEAN = hierarchyTransform(x=CATEGORY2,
                                                         dataset = Category_Rank2))

我得到以下結果。

> NEW_DATA
# A tibble: 5 × 3
     ID CATEGORY1_CLEAN CATEGORY2_CLEAN
   <dbl>           <chr>           <chr>
1    11               E              AA
2    22               B              AA
3    33               C              BB
4    44               A              AA
5    55               B              AA

這正是我想要的,但問題是此操作花費了時間。 我的原始數據集大約有100萬行,當我根據ID進行分組時,我得到了大約200,000個組。 因此,hierarchyTransform函數適用於200,000個組,單個變量大約需要15分鍾,而我必須對其他10個變量執行此操作,這會增加時間。 是否有任何解決方案可以減少此操作所需的時間。

如果您知道CATEGORY級別的等級順序(在您的示例中為字母順序),則可以將CATEGORY轉換為因子,並根據所需排名對等級進行排序。 然后按CATEGORY排序,按ID分組,並為每個ID取第一行。

DUMMY_DATA$CATEGORY = factor(DUMMY_DATA$CATEGORY, levels=LETTERS[1:5], ordered=TRUE)

DUMMY_DATA %>% 
  arrange(ID, CATEGORY) %>%
  group_by(ID) %>%
  slice(1)
  ID CATEGORY 1 11 E 2 22 B 3 33 C 4 44 A 5 55 B 

更新:要回答您的評論和更新的問題:下面的代碼將針對每個ID從每個類別列中選擇最高排名的值。

DUMMY_DATA$CATEGORY1 = factor(DUMMY_DATA$CATEGORY1, levels=LETTERS[1:5], ordered=TRUE)
DUMMY_DATA$CATEGORY2 = factor(DUMMY_DATA$CATEGORY2, levels=c("AA","BB","CC","DD","EE"), ordered=TRUE)

現在,您可以執行以下任一操作:

DUMMY_DATA %>% group_by(ID) %>%
  summarise(CATEGORY1 = min(CATEGORY1),
            CATEGORY2 = min(CATEGORY2))

DUMMY_DATA %>% group_by(ID) %>%
  summarise_all(funs(min))
  ID CATEGORY1 CATEGORY2 1 11 E AA 2 22 B AA 3 33 C BB 4 44 A AA 5 55 B AA 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM