根据 R 中的多列条件查找百分比
Find percentage based on multiple column criteria in R
我有一个具有以下值的数据框:
visitDate espEvent sum(count)
1/2/05 s_All 1352
1/2/05 s_Animal 6
1/2/05 s_CD 4
1/4/05 s_All 1412
1/4/05 s_Animal 4
1/4/05 s_CD 2
我想通过将 espEvent 's_All' 保持在 100%
来找到每个访问日期的值 espEvent 的百分比
生成的数据框应如下所示:
visitDate espEvent sum(count) Percent
1/2/05 s_All 1352 100%
1/2/05 s_Animal 6 0.44%
1/2/05 s_CD 4 0.29%
1/4/05 s_All 1412 100%
1/4/05 s_Animal 4 0.97%
1/4/05 s_CD 2 0.48%
感谢您的帮助!
dplyr
很热衷于这样做。这假设 s_All
将始终是每天的最大值。
df1<-read.table(text="visitDate espEvent count
1/2/05 s_All 1352
1/2/05 s_Animal 6
1/2/05 s_CD 4
1/4/05 s_All 1412
1/4/05 s_Animal 4
1/4/05 s_CD 2",header=TRUE, stringsAsFactors=FALSE)
library(dplyr)
df1 %>%
group_by(visitDate) %>%
mutate(Percent=count/max(count)*100)
visitDate espEvent count Percent
<chr> <chr> <int> <dbl>
1 1/2/05 s_All 1352 100.0000000
2 1/2/05 s_Animal 6 0.4437870
3 1/2/05 s_CD 4 0.2958580
4 1/4/05 s_All 1412 100.0000000
5 1/4/05 s_Animal 4 0.2832861
6 1/4/05 s_CD 2 0.1416431
EDIT 一个不依赖max
的解决方案。
library(dplyr)
df1 %>%
group_by(visitDate) %>%
mutate(percent = count*100/count[espEvent == "s_All"])
visitDate espEvent count.x count.y Percent
<chr> <chr> <int> <int> <dbl>
1 1/2/05 s_All 1352 1352 100.0000000
2 1/2/05 s_Animal 6 1352 0.4437870
3 1/2/05 s_CD 4 1352 0.2958580
4 1/4/05 s_All 1412 1412 100.0000000
5 1/4/05 s_Animal 4 1412 0.2832861
6 1/4/05 s_CD 2 1412 0.1416431
编辑: 来自@thelatemail 的评论,将 .SD
更改为 sum
应该会提高速度。 data.table
的解决方案是:
dt[,percent := sum*100/sum[espEvent=="s_All"], by = (visitDate)]
dt
# visitDate espEvent sum percent
#1: 1/2/05 s_All 1352 100.0000000
#2: 1/2/05 s_Animal 6 0.4437870
#3: 1/2/05 s_CD 4 0.2958580
#4: 1/4/05 s_All 1412 100.0000000
#5: 1/4/05 s_Animal 4 0.2832861
#6: 1/4/05 s_CD 2 0.1416431
这将始终计算相对于 espEvent == "s_All"
行的百分比。
数据:
dt <- structure(list(visitDate = c("1/2/05", "1/2/05", "1/2/05", "1/4/05",
"1/4/05", "1/4/05"), espEvent = c("s_All", "s_Animal", "s_CD",
"s_All", "s_Animal", "s_CD"), sum = c(1352L, 6L, 4L, 1412L, 4L,
2L)), .Names = c("visitDate", "espEvent", "sum"), row.names = c(NA,
-6L), class = c("data.table", "data.frame"))
编辑: 速度测试 - 因为我很好奇,所以我决定使用 sum
和我原来的 .SD
- 看起来像 sum
快得多:
library(microbenchmark)
microbenchmark(sum = dt[,percent := sum*100/sum[espEvent=="s_All"], by = (visitDate)],
.SD = dt[,percent := sum*100/.SD[espEvent=="s_All", sum], by = (visitDate)])
#Unit: microseconds
# expr min lq mean median uq max neval
# sum 814.043 934.400 1035.136 984.082 1105.372 1670.071 100
# .SD 1630.884 1846.173 1987.738 1977.260 2093.886 2496.242 100
我有一个具有以下值的数据框:
visitDate espEvent sum(count)
1/2/05 s_All 1352
1/2/05 s_Animal 6
1/2/05 s_CD 4
1/4/05 s_All 1412
1/4/05 s_Animal 4
1/4/05 s_CD 2
我想通过将 espEvent 's_All' 保持在 100%
来找到每个访问日期的值 espEvent 的百分比生成的数据框应如下所示:
visitDate espEvent sum(count) Percent
1/2/05 s_All 1352 100%
1/2/05 s_Animal 6 0.44%
1/2/05 s_CD 4 0.29%
1/4/05 s_All 1412 100%
1/4/05 s_Animal 4 0.97%
1/4/05 s_CD 2 0.48%
感谢您的帮助!
dplyr
很热衷于这样做。这假设 s_All
将始终是每天的最大值。
df1<-read.table(text="visitDate espEvent count
1/2/05 s_All 1352
1/2/05 s_Animal 6
1/2/05 s_CD 4
1/4/05 s_All 1412
1/4/05 s_Animal 4
1/4/05 s_CD 2",header=TRUE, stringsAsFactors=FALSE)
library(dplyr)
df1 %>%
group_by(visitDate) %>%
mutate(Percent=count/max(count)*100)
visitDate espEvent count Percent
<chr> <chr> <int> <dbl>
1 1/2/05 s_All 1352 100.0000000
2 1/2/05 s_Animal 6 0.4437870
3 1/2/05 s_CD 4 0.2958580
4 1/4/05 s_All 1412 100.0000000
5 1/4/05 s_Animal 4 0.2832861
6 1/4/05 s_CD 2 0.1416431
EDIT 一个不依赖max
的解决方案。
library(dplyr)
df1 %>%
group_by(visitDate) %>%
mutate(percent = count*100/count[espEvent == "s_All"])
visitDate espEvent count.x count.y Percent
<chr> <chr> <int> <int> <dbl>
1 1/2/05 s_All 1352 1352 100.0000000
2 1/2/05 s_Animal 6 1352 0.4437870
3 1/2/05 s_CD 4 1352 0.2958580
4 1/4/05 s_All 1412 1412 100.0000000
5 1/4/05 s_Animal 4 1412 0.2832861
6 1/4/05 s_CD 2 1412 0.1416431
编辑: 来自@thelatemail 的评论,将 .SD
更改为 sum
应该会提高速度。 data.table
的解决方案是:
dt[,percent := sum*100/sum[espEvent=="s_All"], by = (visitDate)]
dt
# visitDate espEvent sum percent
#1: 1/2/05 s_All 1352 100.0000000
#2: 1/2/05 s_Animal 6 0.4437870
#3: 1/2/05 s_CD 4 0.2958580
#4: 1/4/05 s_All 1412 100.0000000
#5: 1/4/05 s_Animal 4 0.2832861
#6: 1/4/05 s_CD 2 0.1416431
这将始终计算相对于 espEvent == "s_All"
行的百分比。
数据:
dt <- structure(list(visitDate = c("1/2/05", "1/2/05", "1/2/05", "1/4/05",
"1/4/05", "1/4/05"), espEvent = c("s_All", "s_Animal", "s_CD",
"s_All", "s_Animal", "s_CD"), sum = c(1352L, 6L, 4L, 1412L, 4L,
2L)), .Names = c("visitDate", "espEvent", "sum"), row.names = c(NA,
-6L), class = c("data.table", "data.frame"))
编辑: 速度测试 - 因为我很好奇,所以我决定使用 sum
和我原来的 .SD
- 看起来像 sum
快得多:
library(microbenchmark)
microbenchmark(sum = dt[,percent := sum*100/sum[espEvent=="s_All"], by = (visitDate)],
.SD = dt[,percent := sum*100/.SD[espEvent=="s_All", sum], by = (visitDate)])
#Unit: microseconds
# expr min lq mean median uq max neval
# sum 814.043 934.400 1035.136 984.082 1105.372 1670.071 100
# .SD 1630.884 1846.173 1987.738 1977.260 2093.886 2496.242 100