对 df 列的子集和 return 总和以及其他列的总计百分比应用条件
Apply condition on subset of df columns and return sum and % of total of other column
我遇到了一个我应该解决但一直无法解决的令人沮丧的问题。给定如下所示的数据框,我想 return,对于每周 W1 到 W4,"amount" 列中的金额和金额百分比基于一个简单的条件。数据集还包含计算时需要忽略的 NA。
我尝试编写一个带有两个参数的函数,首先获取高于我的条件 (100) 的 ID,然后进行数量除法。这是我可笑的努力。
myfxn=function(x, y, na.rm=TRUE) {
count=x>100
with(count,100*(sum(y,na.rm=na.rm)/sum(!is.na(y))))
}
zz=as.data.frame(sapply(exampledata[3:6], myfxn, y=exampledata[2]))
structure(list(ID = 1:10, amount = c(200L, 100L, 300L, 400L,
500L, 200L, 200L, 250L, 150L, 300L), W1 = c(150L, NA, 192L, 143L,
158L, 187L, 173L, NA, 123L, NA), W2 = c(198L, 36L, 86L, 47L,
38L, 109L, 196L, 17L, 188L, NA), W3 = c(50L, 36L, 70L, NA, 45L,
164L, 82L, 169L, 113L, 89L), W4 = c(124L, 18L, 133L, NA, 162L,
23L, 65L, 153L, 145L, 173L)), .Names = c("ID", "amount", "W1",
"W2", "W3", "W4"), class = "data.frame", row.names = c(NA, -10L
))
理想情况下,我的 return 将是一个具有 4 行 (W1:W4) 和 2 列(金额和金额为 %)的 df。谢谢您的帮助!
这里有一个解决方案,虽然有点冗长,但它确实有效,更快的解决方案会涉及更复杂的代码和/或其他包,但这里的解决方案很简单,只使用 dplyr/tidyr/magrittr 希望我理解你答对了:
library(tidyr)
library(magrittr)
library(dplyr)
gather(df, Week, Value, 3:6) %>% filter(Value > 100) %>%
group_by(Week) %>% summarise(Sum.amounts.per.week.over100 = sum(amount)) ->
t.week.over100
gather(df, Week, Value, 3:6) %>%
group_by(Week) %>% filter(!is.na(Value)) %>%
summarise(Sum.amounts.per.week.total = sum(amount)) -> t.week.total
t.week <- merge(t.week.over100, t.week.total, by = "Week")
t.week$percent <- t.week$Sum.amounts.per.week.over100/t.week$Sum.amounts.per.week.total * 100
如果您希望百分比四舍五入:
t.week$percent <- round(t.week$percent)
我强烈建议您查看一些关于 tidyr/dplyr 和 magrittr 的教程,尤其是前两个,例如:
我遇到了一个我应该解决但一直无法解决的令人沮丧的问题。给定如下所示的数据框,我想 return,对于每周 W1 到 W4,"amount" 列中的金额和金额百分比基于一个简单的条件。数据集还包含计算时需要忽略的 NA。
我尝试编写一个带有两个参数的函数,首先获取高于我的条件 (100) 的 ID,然后进行数量除法。这是我可笑的努力。
myfxn=function(x, y, na.rm=TRUE) {
count=x>100
with(count,100*(sum(y,na.rm=na.rm)/sum(!is.na(y))))
}
zz=as.data.frame(sapply(exampledata[3:6], myfxn, y=exampledata[2]))
structure(list(ID = 1:10, amount = c(200L, 100L, 300L, 400L,
500L, 200L, 200L, 250L, 150L, 300L), W1 = c(150L, NA, 192L, 143L,
158L, 187L, 173L, NA, 123L, NA), W2 = c(198L, 36L, 86L, 47L,
38L, 109L, 196L, 17L, 188L, NA), W3 = c(50L, 36L, 70L, NA, 45L,
164L, 82L, 169L, 113L, 89L), W4 = c(124L, 18L, 133L, NA, 162L,
23L, 65L, 153L, 145L, 173L)), .Names = c("ID", "amount", "W1",
"W2", "W3", "W4"), class = "data.frame", row.names = c(NA, -10L
))
理想情况下,我的 return 将是一个具有 4 行 (W1:W4) 和 2 列(金额和金额为 %)的 df。谢谢您的帮助!
这里有一个解决方案,虽然有点冗长,但它确实有效,更快的解决方案会涉及更复杂的代码和/或其他包,但这里的解决方案很简单,只使用 dplyr/tidyr/magrittr 希望我理解你答对了:
library(tidyr)
library(magrittr)
library(dplyr)
gather(df, Week, Value, 3:6) %>% filter(Value > 100) %>%
group_by(Week) %>% summarise(Sum.amounts.per.week.over100 = sum(amount)) ->
t.week.over100
gather(df, Week, Value, 3:6) %>%
group_by(Week) %>% filter(!is.na(Value)) %>%
summarise(Sum.amounts.per.week.total = sum(amount)) -> t.week.total
t.week <- merge(t.week.over100, t.week.total, by = "Week")
t.week$percent <- t.week$Sum.amounts.per.week.over100/t.week$Sum.amounts.per.week.total * 100
如果您希望百分比四舍五入:
t.week$percent <- round(t.week$percent)
我强烈建议您查看一些关于 tidyr/dplyr 和 magrittr 的教程,尤其是前两个,例如: