[英]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
:
group_id
內的唯一和有序distance
group_id
d1,d2,...,d_n
。 d1,d2,...,d_n
每個d
在distance
值小於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_int
, map_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.