2017-04-19 50 views
1

我已經與下列值的數據幀百分比:查找基於多列標準中的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的百分比每次訪問日期通過保持espEvent「s_All」在100%

產生的數據幀應該如下:

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% 

感謝您的幫助!

回答

3

編輯:從@ thelatemail的評論,改變.SDsum這應該提高速度。一個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 
+1

沒有必要使用'.SD' - 'dat [,percent:= sum * 100/sum [espEvent ==「s_All」],by = visitDate]'就可以做到。在一個大的數據集中,這會在速度上產生巨大的相對差異。 – thelatemail

+0

@thelatemail謝謝!我會更新我的答案 –

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 
+0

嗨, 非常感謝!這正是我一直在尋找的! 順便說一句,有沒有辦法做到這一點,忽略s_All將始終爲最大的事實? 再次感謝 –

+1

@DollarVora看到我的編輯 –

+1

它可以用與'data.table'完全相同的方式創建:'df1%>%group_by(visitDate)%>%mutate(percent = count * 100/count [espEvent ==「s_All」])' –