r - 汇总时处理可能丢失的列的最佳方法是什么?
问题描述
财务报表很好地说明了这个问题。这是一个示例数据框:
df <- data.frame( date = sample(seq(as.Date('2020/01/01'), as.Date('2020/12/31'), by="day"), 10),
category = sample(c('a','b', 'c'), 10, replace=TRUE),
direction = sample(c('credit', 'debit'), 10, replace=TRUE),
value = sample(0:25, 10, replace = TRUE) )
我想为每个类别生成一个包含incoming
,outgoing
和列的汇总表。total
df %>%
pivot_wider(names_from = direction, values_from = value) %>%
group_by(category) %>%
summarize(incoming = sum(credit, na.rm=TRUE), outgoing=sum(debit,na.rm=TRUE) ) %>%
mutate(total= incoming-outgoing)
在大多数情况下,这与上面的示例数据框完美配合。
但在某些情况下,df$direction
可能包含单个值,例如credit
,从而导致错误。
Error: Problem with `summarise()` column `outgoing`.
object 'debit' not found
鉴于我无法控制数据框,处理此问题的最佳方法是什么?
我一直在使用 summarise 方法中的条件语句来检查列是否存在,但没有设法让它工作。
...
summarize( outgoing = case_when(
"debit" %in% colnames(.) ~ sum(debit,na.rm=TRUE),
TRUE ~ 0 ) )
...
我是否犯了语法错误,或者我的方向完全错误?
解决方案
只有当其中一个元素出现时,即“贷方”而没有“借方”或反之亦然,才会出现此问题。然后,pivot_wider
不会创建缺少的列。而不是旋转然后汇总,而是直接使用summarise
and执行此操作,==
即如果“借方”不存在,sum
将通过返回 0 来处理它
library(dplyr)
df %>%
slice(-c(9:10)) %>% # just removed the 'debit' rows completely
group_by(category) %>%
summarise(total = sum(value[direction == 'credit']) -
sum(value[direction == "debit"]))
-输出
# A tibble: 3 × 2
category total
<chr> <int>
1 a 15
2 b 30
3 c 63
,pivot_wider
情况并非如此
df %>%
slice(-c(9:10)) %>%
pivot_wider(names_from = direction, values_from = value)
# A tibble: 8 × 3
date category credit
<date> <chr> <int>
1 2020-07-25 c 19
2 2020-05-09 b 15
3 2020-08-27 a 15
4 2020-03-27 b 15
5 2020-04-06 c 6
6 2020-07-06 c 11
7 2020-09-22 c 25
8 2020-10-06 c 2
它只创建“贷方”列,因此当我们调用未创建的“借方”列时,它会引发错误
df %>%
slice(-c(9:10)) %>%
pivot_wider(names_from = direction, values_from = value) %>%
group_by(category) %>%
summarize(incoming = sum(credit, na.rm=TRUE),
outgoing=sum(debit,na.rm=TRUE) )
错误:
summarise()
列有问题outgoing
。ℹoutgoing = sum(debit, na.rm = TRUE)
。✖ 未找到对象“借方”ℹ 组 1 中发生错误:类别 =“a”。运行rlang::last_error()
以查看错误发生的位置。
在这种情况下,我们可以complete
创建一些行,这些行debit
也将NA
用于其他列
library(tidyr)
df %>%
slice(-c(9:10)) %>%
complete(category, direction = c("credit", "debit")) %>%
pivot_wider(names_from = direction, values_from = value) %>%
group_by(category) %>%
summarize(incoming = sum(credit, na.rm=TRUE),
outgoing=sum(debit,na.rm=TRUE) ) %>%
mutate(total= incoming-outgoing)
# A tibble: 3 × 4
category incoming outgoing total
<chr> <int> <int> <int>
1 a 15 0 15
2 b 30 0 30
3 c 63 0 63
推荐阅读
- javascript - 从 mongodb 数据库返回一个值
- laravel - 成就系统 - 关系检查是否满足条件,总分
- html - 如何在 django 中通过 ajax 接收和保存数据?
- graphql - GraphQL 中的嵌套查询
- mule-studio - 为什么我的 dataweave 地图代码不起作用?
- python - 使用 Model.objects.all() 作为辅助表条目的蓝图
- python - 从 Python 中的 QListWidgetItem 调用带有单击项的函数
- php - cURL 忽略 CURLOPT_HTTPHEADER
- sql-server - SQL Server 2016 使用 SQL Server 导入和导出向导挂起
- azure - Azure 服务重复消息转发