2015-10-17 76 views
1

考慮下面的數據幀:變換頻率的因子水平成比例

x <-c(rep (c ("s1", "s2", "s3"),each=5)) 
y <- c(rep(c("a", "b", "c", "d", "e"), 3))    
z<-c(1:15)  

x_name <- "dimensions" 
y_name <- "aspects" 
z_name<-"value" 
df <- data.frame(x,y,z) 
names(df) <- c(x_name,y_name, z_name) 

我怎麼能計算和添加比例的新列各因素的水平?在'value'每個'dimension''aspects'這種情況下百分比,這樣我有這樣的事情:

enter image description here

爲了說明:在percentage 7表示的value 1從合計值的取aspects下對應於dimension百分比s1(在這種情況下爲15)等

我搜索了論壇,但創建百分比的答案只能跨一列而不是兩列。我最終通過使用aggregate首先計算了跨維度方面的df總值,然後生成了此列。然後我將最初的df與新的merge合併,並通過將值列除以總值來創建百分比列。但我覺得這很笨拙。有沒有更簡單的方法來做到這一點?

回答

2

在基礎R您可以使用ave做分組計算的這些類型:

df$percentage <- ave(df$value, df$dimensions, FUN=function(x) 100*x/sum(x)) 
df 
# dimensions aspects value percentage 
# 1   s1  a  1 6.666667 
# 2   s1  b  2 13.333333 
# 3   s1  c  3 20.000000 
# 4   s1  d  4 26.666667 
# 5   s1  e  5 33.333333 
# 6   s2  a  6 15.000000 
# 7   s2  b  7 17.500000 
# 8   s2  c  8 20.000000 
# 9   s2  d  9 22.500000 
# 10   s2  e 10 25.000000 
# 11   s3  a 11 16.923077 
# 12   s3  b 12 18.461538 
# 13   s3  c 13 20.000000 
# 14   s3  d 14 21.538462 
# 15   s3  e 15 23.076923 

在dplyr你可以使用group_bymutate

library(dplyr) 
df %>% group_by(dimensions) %>% mutate(percentage=100*value/sum(value)) 
# Source: local data frame [15 x 4] 
# Groups: dimensions [3] 
# 
# dimensions aspects value percentage 
#  (fctr) (fctr) (int)  (dbl) 
# 1   s1  a  1 6.666667 
# 2   s1  b  2 13.333333 
# 3   s1  c  3 20.000000 
# 4   s1  d  4 26.666667 
# 5   s1  e  5 33.333333 
# 6   s2  a  6 15.000000 
# 7   s2  b  7 17.500000 
# 8   s2  c  8 20.000000 
# 9   s2  d  9 22.500000 
# 10   s2  e 10 25.000000 
# 11   s3  a 11 16.923077 
# 12   s3  b 12 18.461538 
# 13   s3  c 13 20.000000 
# 14   s3  d 14 21.538462 
# 15   s3  e 15 23.076923 

可以通過將百分比計算包裝在round函數中並傳遞所需的精度來執行任何所需的舍入。

3

您可以使用round和快速data.table方法:

library(data.table) 
setDT(df)[,percentage:=round(100*value/sum(value)), dimensions][] 

# dimensions aspects value percentage 
# 1:   s1  a  1   7 
# 2:   s1  b  2   13 
# 3:   s1  c  3   20 
# 4:   s1  d  4   27 
# 5:   s1  e  5   33 
# 6:   s2  a  6   15 
# 7:   s2  b  7   18 
# 8:   s2  c  8   20 
# 9:   s2  d  9   22 
#10:   s2  e 10   25 
#11:   s3  a 11   17 
#12:   s3  b 12   18 
#13:   s3  c 13   20 
#14:   s3  d 14   22 
#15:   s3  e 15   23