R reshape2 or dplyr/tidyr: 计算值占小计的百分比
R reshape2 or dplyr/tidyr: calculating values' percentage of sub-total
让我们以空气质量数据集为基础。
myaqm <- melt(airquality, id=c("Month", "Day"), na.rm = TRUE)
这简化了我的真实数据集。到目前为止,我已经这样做了:
myaqm_dcast <- dcast(myaqm, Day+variable~Month, value.var = "value", sum, margins=c("Day", "variable", "Month"))
这给了我这个:
> head(myaqm_dcast, n=10)
Day variable 5 6 7 8 9 (all)
1 1 Ozone 41.0 0.0 135.0 39.0 96.0 311.0
2 1 Solar.R 190.0 286.0 269.0 83.0 167.0 995.0
3 1 Wind 7.4 8.6 4.1 6.9 6.9 33.9
4 1 Temp 67.0 78.0 84.0 81.0 91.0 401.0
5 1 (all) 305.4 372.6 492.1 209.9 360.9 1740.9
6 2 Ozone 36.0 0.0 49.0 9.0 78.0 172.0
7 2 Solar.R 118.0 287.0 248.0 24.0 197.0 874.0
8 2 Wind 8.0 9.7 9.2 13.8 5.1 45.8
9 2 Temp 72.0 74.0 85.0 81.0 92.0 404.0
10 2 (all) 234.0 370.7 391.2 127.8 372.1 1495.8
但是,我正在尝试为每个当前数字列创建一个额外的 variables'-percentage-of-days'-subtotal 列。所以我的目标是:
Day variable 5 5(day %) 6 6(day %) 7 7(day %) 8 8(day %) 9 9(day %) (all) (all)(day %)
1 Ozone 41 13.4% 0 0.0% 135 27.4% 39 18.6% 96 26.6% 311 17.9%
1 Solar.R 190 62.2% 286 76.8% 269 54.7% 83 39.5% 167 46.3% 995 57.2%
1 Wind 7.4 2.4% 8.6 2.3% 4.1 0.8% 6.9 3.3% 6.9 1.9% 33.9 1.9%
1 Temp 67 21.9% 78 20.9% 84 17.1% 81 38.6% 91 25.2% 401 23.0%
1 (all) 305.4 100.0% 372.6 100.0% 492.1 100.0% 209.9 100.0% 360.9 100.0% 1740.9 100.0%
2 Ozone 36 15.4% 0 0.0% 49 12.5% 9 7.0% 78 21.0% 172 11.5%
2 Solar.R 118 50.4% 287 77.4% 248 63.4% 24 18.8% 197 52.9% 874 58.4%
2 Wind 8 3.4% 9.7 2.6% 9.2 2.4% 13.8 10.8% 5.1 1.4% 45.8 3.1%
2 Temp 72 30.8% 74 20.0% 85 21.7% 81 63.4% 92 24.7% 404 27.0%
2 (all) 234 100.0% 370.7 100.0% 391.2 100.0% 127.8 100.0% 372.1 100.0% 1495.8 100.0%
抱歉格式太糟糕了!但正如您希望看到的那样,新的附加列给出了当天和该月每个变量的百分比。
我发现另一个 Stack Overflow 助手建议使用 tidyr 和 dplyr,但我无法根据我的需要调整他们的示例。有人可以告诉我该怎么做吗?
我编写了一个百分比函数并将其与 dplyr 一起使用。然后我将列连接在一起。
pct <- function(x) {x/sum(x)}
df <- myaqm_dcast %>%
filter(variable != "(all)") %>%
group_by(Day) %>%
mutate_each(funs(pct), 3:8) %>%
inner_join(myaqm_dcast, by = c("Day", "variable"))
编辑:您可以修改百分比函数以根据需要进行打印(*100,粘贴 % 符号)。
编辑 2:如果您可以在没有(所有)行的情况下生活,我已经将其过滤掉了。您始终可以使用 summarise_each() 函数计算列总和。
为什么要重塑数据? Dataframe myaqm满足tidy data的要求(每一列是一个变量,每一行是一个观察值)。您可以按以下格式进行计算:
library(dplyr)
myaqm %>%
group_by(Day, variable) %>%
mutate(all = sum(value),
perc = paste0(round(100 * value/all, 2), "%")
即使是创建绘图(例如通过 ggplot),这种格式也比重塑后的格式更适合。
如果确实有必要,您可以使用 tidyr/dplyr 进行整形:
...
gather(key, val, -c(Month:variable, all)) %>%
unite(temp, Month, key) %>%
spread(temp, val)
让我们以空气质量数据集为基础。
myaqm <- melt(airquality, id=c("Month", "Day"), na.rm = TRUE)
这简化了我的真实数据集。到目前为止,我已经这样做了:
myaqm_dcast <- dcast(myaqm, Day+variable~Month, value.var = "value", sum, margins=c("Day", "variable", "Month"))
这给了我这个:
> head(myaqm_dcast, n=10)
Day variable 5 6 7 8 9 (all)
1 1 Ozone 41.0 0.0 135.0 39.0 96.0 311.0
2 1 Solar.R 190.0 286.0 269.0 83.0 167.0 995.0
3 1 Wind 7.4 8.6 4.1 6.9 6.9 33.9
4 1 Temp 67.0 78.0 84.0 81.0 91.0 401.0
5 1 (all) 305.4 372.6 492.1 209.9 360.9 1740.9
6 2 Ozone 36.0 0.0 49.0 9.0 78.0 172.0
7 2 Solar.R 118.0 287.0 248.0 24.0 197.0 874.0
8 2 Wind 8.0 9.7 9.2 13.8 5.1 45.8
9 2 Temp 72.0 74.0 85.0 81.0 92.0 404.0
10 2 (all) 234.0 370.7 391.2 127.8 372.1 1495.8
但是,我正在尝试为每个当前数字列创建一个额外的 variables'-percentage-of-days'-subtotal 列。所以我的目标是:
Day variable 5 5(day %) 6 6(day %) 7 7(day %) 8 8(day %) 9 9(day %) (all) (all)(day %)
1 Ozone 41 13.4% 0 0.0% 135 27.4% 39 18.6% 96 26.6% 311 17.9%
1 Solar.R 190 62.2% 286 76.8% 269 54.7% 83 39.5% 167 46.3% 995 57.2%
1 Wind 7.4 2.4% 8.6 2.3% 4.1 0.8% 6.9 3.3% 6.9 1.9% 33.9 1.9%
1 Temp 67 21.9% 78 20.9% 84 17.1% 81 38.6% 91 25.2% 401 23.0%
1 (all) 305.4 100.0% 372.6 100.0% 492.1 100.0% 209.9 100.0% 360.9 100.0% 1740.9 100.0%
2 Ozone 36 15.4% 0 0.0% 49 12.5% 9 7.0% 78 21.0% 172 11.5%
2 Solar.R 118 50.4% 287 77.4% 248 63.4% 24 18.8% 197 52.9% 874 58.4%
2 Wind 8 3.4% 9.7 2.6% 9.2 2.4% 13.8 10.8% 5.1 1.4% 45.8 3.1%
2 Temp 72 30.8% 74 20.0% 85 21.7% 81 63.4% 92 24.7% 404 27.0%
2 (all) 234 100.0% 370.7 100.0% 391.2 100.0% 127.8 100.0% 372.1 100.0% 1495.8 100.0%
抱歉格式太糟糕了!但正如您希望看到的那样,新的附加列给出了当天和该月每个变量的百分比。
我发现另一个 Stack Overflow 助手建议使用 tidyr 和 dplyr,但我无法根据我的需要调整他们的示例。有人可以告诉我该怎么做吗?
我编写了一个百分比函数并将其与 dplyr 一起使用。然后我将列连接在一起。
pct <- function(x) {x/sum(x)}
df <- myaqm_dcast %>%
filter(variable != "(all)") %>%
group_by(Day) %>%
mutate_each(funs(pct), 3:8) %>%
inner_join(myaqm_dcast, by = c("Day", "variable"))
编辑:您可以修改百分比函数以根据需要进行打印(*100,粘贴 % 符号)。
编辑 2:如果您可以在没有(所有)行的情况下生活,我已经将其过滤掉了。您始终可以使用 summarise_each() 函数计算列总和。
为什么要重塑数据? Dataframe myaqm满足tidy data的要求(每一列是一个变量,每一行是一个观察值)。您可以按以下格式进行计算:
library(dplyr)
myaqm %>%
group_by(Day, variable) %>%
mutate(all = sum(value),
perc = paste0(round(100 * value/all, 2), "%")
即使是创建绘图(例如通过 ggplot),这种格式也比重塑后的格式更适合。
如果确实有必要,您可以使用 tidyr/dplyr 进行整形:
...
gather(key, val, -c(Month:variable, all)) %>%
unite(temp, Month, key) %>%
spread(temp, val)