我已重写问题,希望它更有意义。
提供此数据:
> df
Cat1 Cat2 Q
1 A B 1
2 A C 1
3 B D 1
4 B C 1
5 C C 1
6 C D 1
您可以使用dplyr轻松group by
Cat1
和sum
Q
:
> df %>% group_by(Cat1) %>% summarise(Sum1 = sum(Q))
# A tibble: 3 x 2
Cat1 Sum1
<fct> <dbl>
1 A 2
2 B 2
3 C 2
现在,我的问题是,下一步,您是否可以使用group by
中的组(即A
,B
和C
)在原始表中操作?例如,当sum
等于每个组时,您怎么Q
Cat2
?
意思是,对于A
,Cat2
中没有匹配项,因此Q
的总和为0
。对于B
,第一行中只有一个匹配项,因此Q
的总和为1
。对于C
,在第二行,第四行和第五行中都有一个匹配项,因此Q
的总和为3
:
# A tibble: 3 x 3
Cat1 Sum1 Sum2
<fct> <dbl> <dbl>
1 A 2 0
2 B 2 1
3 C 2 3
请注意,这不是我要的不是:
> df %>% group_by(Cat1) %>% summarise(Sum1 = sum(Q), Sum2 = sum(Q[Cat1==Cat2]))
# A tibble: 3 x 3
Cat1 Sum1 Sum2
<fct> <dbl> <dbl>
1 A 2 0
2 B 2 0
3 C 2 1
@ antoine-sac在注释中建议复制df
,并在Cat1(Grouped) = Cat2
上进行左连接。当然,这可以解决问题,但这不是我要回答的问题。
代码:
Cat1 <- c("A","A","B","B","C","C")
Cat2 <- c("B","C","D","C","C","D")
Cat1 <- factor(Cat1, levels = c("A","B","C","D"))
Cat2 <- factor(Cat2, levels = c("A","B","C","D"))
Q <- c(1,1,1,1,1,1)
df <- data.frame(Cat1, Cat2, Q)
答案 0 :(得分:1)
您可以尝试
df %>%
group_by(Cat1) %>%
summarise(sum1 = sum(Q),
sum2 = sum(ifelse(.$Cat2 == Cat1[1], Q, 0)))
# A tibble: 3 x 3
Cat1 sum1 sum2
<fct> <dbl> <dbl>
1 A 2 0
2 B 2 1
3 C 2 3
使用.$
,您将比较并汇总未分组的原始数据。
答案 1 :(得分:1)
我认为join
是最干净的方法。考虑一下自己在6个月内再次阅读代码:您希望代码的含义显而易见。
library("dplyr")
df <- read.table(text = " Cat1 Cat2 Q
1 A B 1
2 A C 1
3 B D 1
4 B C 1
5 C C 1
6 C D 1", stringsAsFactor = FALSE)
df1 <- df %>%
group_by(Cat1) %>%
summarise(Sum1 = sum(Q))
df2 <- df %>%
group_by(Cat2) %>%
summarise(Sum2 = sum(Q))
full_join(df1, df2, by = c("Cat1" = "Cat2")) %>%
tidyr::replace_na(list(Sum1 = 0, Sum2 = 0))
# # A tibble: 4 x 3
# Cat1 Sum1 Sum2
# <chr> <dbl> <dbl>
# 1 A 2 0
# 2 B 2 1
# 3 C 2 3
# 4 D 0 2
使用full_join
,您可以将所有值保留在Cat1
或Cat2
中(A,B,C和D),但可以使用left_join
(保留A ,B,C),right_join
(保留B,C,D)或inner_join
(保留B,C)。
这些分别是Cat1
,Cat2
中的值,或者是Cat1
和 Cat2
中的值。
这似乎很痛苦,特别是如果您有很多类别,但是如果必须执行多次以上,则实际上很容易在函数中实现自动化。
编辑:实际上,由于非标准评估,如果要使用dplyr根本不容易。这是您的操作方式:
sum_cats <- function(df, cat1, cat2, value) {
cat1 <- enquo(cat1)
cat2 <- enquo(cat2)
value <- enquo(value)
sum1 <- paste0("Sum_", quo_name(cat1))
df1 <- df %>%
rename(cat = !! cat1) %>%
group_by(cat) %>%
summarise(!! sum1 := sum(!! value))
sum2 <- paste0("Sum_", quo_name(cat2))
df2 <- df %>%
rename(cat = !! cat2) %>%
group_by(cat) %>%
summarise(!! sum2 := sum(!! value))
full_join(df1, df2, by = "cat") %>%
tidyr::replace_na(rlang::list2(!! sum1 := 0, !! sum2 := 0))
}
现在,您只需致电sum_cats
即可完成所有工作:
df %>%
sum_cats(Cat1, Cat2, Q)
# cat Sum_Cat1 Sum_Cat2
# <chr> <dbl> <dbl>
# 1 A 2 0
# 2 B 2 1
# 3 C 2 3
# 4 D 0 2
答案 2 :(得分:0)
您可能可以构造一个新列并从该新列中进行总结:
df %>% mutate(new_Quantity=ifelse(Start == End, Quantity,0)) %>% group_by(Start) %>% summarise(Sum = sum(new_Quantity))