2014-12-22 7 views
1

Я пытаюсь сделать карту тепла некоторых результатов опроса о местных инфраструктурных проектах. Опрос попросил людей предсказать, каковы будут основные издержки и основные преимущества проекта. Я уже использовал ggplot для создания простой схемы издержек и преимуществ. Теперь я хотел бы создать новый столбец «частота» в наборе данных (см. Ниже), который нормализуется в зависимости от общей категории для каждого элемента в столбце «стоимость». Поэтому я бы хотел, чтобы первые четыре элемента в «Частоте2» были соответствующим элементом в столбце «Частота», разделенным на общее число людей, которые сказали, что цены на жилье являются основной стоимостью (61), а затем умножаются на 100, чтобы дать процент. Есть ли быстрый способ сделать это в R? В Excel я бы использовал sumif для получения итогов по категориям, а затем просто использовал оператор if для создания нового столбца. Существует ли аналогичный процесс в R? Благодаря!Новый столбец данных данных на существующей колонке

 Benefits Costs   Frequency 
14 Local Comp Housing Prices 8 
16   Jobs Housing Prices 26 
17   Other Housing Prices 0 
18   None Housing Prices 27 
20 Local Comp   Traffic 7 
22   Jobs   Traffic 17 
23   Other   Traffic 1 
24   None   Traffic 11 

данных

df <- data.frame(Benefits=c("Local Comp", "Jobs", "Other", "None", "Local Comp", "Jobs", "Other", "None"), 
Costs=c("Housing Prices", "Housing Prices", "Housing Prices", "Housing Prices", "Traffic", "Traffic", "Traffic", "Traffic"), 
Frequency=c(8,26,0,27,7,17,1,11)) 

ответ

3

Вы можете использовать ave вычислить сумму частот для каждой группы. Я делаю это внутри transform:

transform(df, Frequency2 = Frequency/ave(Frequency, Costs, FUN = sum) * 100) 
#  Benefits   Costs Frequency Frequency2 
#14 Local_Comp Housing_Prices   8 13.114754 
#16  Jobs Housing_Prices  26 42.622951 
#17  Other Housing_Prices   0 0.000000 
#18  None Housing_Prices  27 44.262295 
#20 Local_Comp  Traffic   7 19.444444 
#22  Jobs  Traffic  17 47.222222 
#23  Other  Traffic   1 2.777778 
#24  None  Traffic  11 30.555556 

Или, если у вас есть очень большой набор данных, вы можете использовать dplyr для повышения производительности:

library(dplyr) 
df %>% group_by(Costs) %>% mutate(Frequency2 = Frequency/sum(Frequency) * 100) 
#Source: local data frame [8 x 4] 
#Groups: Costs 
# 
# Benefits   Costs Frequency Frequency2 
#1 Local_Comp Housing_Prices   8 13.114754 
#2  Jobs Housing_Prices  26 42.622951 
#3  Other Housing_Prices   0 0.000000 
#4  None Housing_Prices  27 44.262295 
#5 Local_Comp  Traffic   7 19.444444 
#6  Jobs  Traffic  17 47.222222 
#7  Other  Traffic   1 2.777778 
#8  None  Traffic  11 30.555556 

Или с помощью data.table:

library(data.table) 
setDT(df)[, Frequency2 := Frequency/sum(Frequency) * 100, by = Costs ] 
+0

Часть 'data.table' скрыта. Вы можете сохранить некоторые нажатия клавиш, удалив 'by =' btw –

+1

Ха-ха! Представьте, сколько еще времени мне нужно было бы потратить на удаление этих четырех символов из моего ответа: D @DavidArenburg –

+2

Мне потребовалось больше времени, чем @docendodiscimus, но я придумал 'df%>% group_by (Costs)%>% mutate (Frequency2 = Частота/сумма (частота) * 100) 'также –