[英]R: Sum Two Lists Embedded in Rows of a Dataframe by Groups
我有关于债券组及其现金流量的数据。 每个 IssueID 包含多个 BondID。 每个 BondID 都有自己的现金流,通过 dplyr 变异在数据框中呈现为列表。 现金流量列表没有相同数量的元素。 数据结构为:
问题ID | 债券编号 | 现金周转 |
---|---|---|
AA | AA1 | c(-1000, 50, 50, 1050) |
AA | AA2 | c(-1000, 25, 25, 25, 25, 1025) |
AB | AB1 | c(-2000, 100, 100, 2100) |
AB | AB1 | c(-1000, 75, 75, 75, 75, 1075) |
我需要按 IssueID 对每个 BondID 的现金流求和,同时在列表中维护每个元素的 position。 output 需要看起来像:
问题ID | 总现金流量 |
---|---|
AA | c(-2000, 75, 75, 1075, 25, 1025) |
AB | c(-3000, 175, 175, 2175, 75, 1075) |
感谢任何帮助。 谢谢。
我无法总结列表。
这是一个选项 - 按“IssueID”分组,将cashflow
列表转换为带序列的命名list
( row_number()
),然后使用enframe
转换为unnest
,取消list
列的嵌套,按“名称”的rowid
创建分组'(如果长度不等),并获取'value'的sum
,将列作为list
pull
library(dplyr)
library(tibble)
library(tidyr)
library(data.table)
out <- df1 %>%
group_by(IssueID) %>%
summarise(sumcashflow = setNames(cashflow, row_number()) %>%
enframe %>%
unnest(value) %>%
group_by(grp = rowid(name)) %>%
summarise(value = sum(value, na.rm = TRUE)) %>%
pull(value) %>%
list(.))
-输出
> out$sumcashflow
[[1]]
[1] -2000 75 75 1075 25 1025
[[2]]
[1] -3000 175 175 2175 75 1075
> out
# A tibble: 2 × 2
IssueID sumcashflow
<chr> <list>
1 AA <dbl [6]>
2 AB <dbl [6]>
或使用base R
split
lst1 <- lapply(split(df1$cashflow, df1$IssueID), \(x) {
mx <- max(lengths(x))
rowSums(sapply(x, `length<-`, mx), na.rm = TRUE)
})
> lst1
$AA
[1] -2000 75 75 1075 25 1025
$AB
[1] -3000 175 175 2175 75 1075
df1 <- structure(list(IssueID = c("AA", "AA", "AB", "AB"), BondID = c("AA1",
"AA2", "AB1", "AB1"), cashflow = list(c(-1000, 50, 50, 1050),
c(-1000, 25, 25, 25, 25, 1025), c(-2000, 100, 100, 2100),
c(-1000, 75, 75, 75, 75, 1075))), row.names = c(NA, -4L), class = c("tbl_df",
"tbl", "data.frame"))
df1 %>%
group_by(IssueID) %>%
summarise(val = list(colSums(do.call(qpcR:::rbind.na, cashflow), na.rm = TRUE)))
# A tibble: 2 x 2
IssueID val
<chr> <list>
1 AA <dbl [6]>
2 AB <dbl [6]>
val:
[[1]]
[1] -2000 75 75 1075 25 1025
[[2]]
[1] -3000 175 175 2175 75 1075
可以写一个小的function,应用到每个IssueID
f <- function(cf) {
ml = lengths(cf)
for(i in seq_along(ml)) {
if(length(cf[[i]])<max(ml)) cf[[i]]=c(cf[[i]],rep(0,max(ml)-length(cf[[i]])))
}
list(rowSums(matrix(unlist(cf),ncol=length(cf))))
}
使用dplyr
:
d %>% group_by(IssueID) %>% summarize(sumcashflow = f(cashflow))
使用data.table
:
setDT(d)[,.(f(cashflow)), by=IssueID]
Output:
IssueID sumcashflow
1: AA -2000, 75, 75, 1075, 25, 1025
2: AB -3000, 175, 175, 2175, 75, 1075
输入:
d = data.table(
IssueID = c("AA","AA","AB","AB"),
BondID = c("AA1", "AA2","AB1", "AB2"),
cashflow = list(c(-1000,50,50,1050),
c(-1000,25,25,25,25,1025),
c(-2000,100,100,2100),
c(-1000,75,75,75,75,1075))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.