我有一个包含以下值的数据框:
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%
感谢您的帮助!
答案 0 :(得分:3)
在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
编辑不依赖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
答案 1 :(得分:3)
编辑:从@ 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