簡體   English   中英

重復將條件摘要應用於數據框中的組

[英]Repeatedly apply a conditional summary to groups in a dataframe

我有一個大型數據框,如下所示:

group_id    distance    metric
       1         1.1      0.85
       1         1.1      0.37
       1         1.7      0.93   
       1         2.3      0.45 
       ...
       1         6.3      0.29
       1         7.9      0.12
       2         2.5      0.78
       2         2.8      0.32
       ...

數據幀已按group_id排序,然后按distance排序。 我想知道dplyr或data.table等效於執行以下操作:

在每個group_id

  1. 讓當前group_id內的唯一和有序distance group_id d1,d2,...,d_n
  2. 對於d1,d2,...,d_n每個ddistance值小於d所有metric上計算一些函數f 函數f是一個自定義用戶定義的函數,它接受一個向量並返回一個標量。 假設函數f在空向量上很好地定義。

因此,在上面的示例中,所需的數據框將如下所示:

group_id    distance_less_than    metric
       1                   1.1      f(empty vector)
       1                   1.7      f(0.85, 0.37)
       1                   2.3      f(0.85, 0.37, 0.93) 
       ...
       1                   7.9      f(0.85, 0.37, 0.93, 0.45,...,0.29)
       2                   2.5      f(empty vector)
       2                   2.8      f(0.78)
       ...

注意distance值如何重復,如組1下的值1.1 在這種情況下,當距離小於1.1時,應排除這兩行(在這種情況下,這會導致空向量)。

一種可能的方法是使用data.table提供的非等連接。 左表是group_id和distance的唯一組合,右表的所有距離都小於左表的距離。

f <- sum
DT[unique(DT, by=c("group_id", "distance")), on=.(group_id, distance<distance), allow.cartesian=TRUE,
    f(metric), by=.EACHI]

輸出:

   group_id distance   V1
1:        1      1.1   NA
2:        1      1.7 1.22
3:        1      2.3 2.15
4:        1      6.3 2.60
5:        1      7.9 2.89
6:        2      2.5   NA
7:        2      2.8 0.78

數據:

library(data.table)
DT <- fread("group_id    distance    metric
1         1.1      0.85
1         1.1      0.37
1         1.7      0.93   
1         2.3      0.45 
1         6.3      0.29
1         7.9      0.12
2         2.5      0.78
2         2.8      0.32")

不要認為這比data.table選項更快,但這是使用dplyr一種方法

library(dplyr)

df %>%
  group_by(group_id) %>%
  mutate(new = purrr::map_dbl(distance, ~f(metric[distance < .])))

其中f是你的功能。 map_dbl期望函數的返回類型為double。 如果您的函數具有不同的返回類型,則可能需要使用map_intmap_chr或like。

如果您希望每個distance只保留一個條目,則可以使用filter刪除它們並duplicated

df %>%
  group_by(group_id) %>%
  mutate(new = purrr::map_dbl(distance, ~f(metric[distance < .]))) %>%
  filter(!duplicated(distance))

暫無
暫無

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

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