Как упорядочить уровни в переменной на основе как суммы значений в переменной, так и уровней в другой переменной?
У меня есть фрейм данных, похожий на этот, который я готовлю для ggplot:
txt <- "v1 v2 v3
'Strongly agree' 83.1 var1
'Agree' 14.9 var1
'Disagree' 1.5 var1
'Strongly disagree' 0.6 var1
'Strongly agree' 11.8 var2
'Agree' 36.5 var2
'Disagree' 17.7 var2
'Strongly disagree' 43.8 var2
'Strongly agree' 19.6 var3
'Agree' 12 var3
'Disagree' 31.6 var3
'Strongly disagree' 36.8 var3"
mydata <- read.table(textConnection(txt), sep = " ", header = TRUE)
Мой вопрос: как заказать уровни в mydata$v3
на основе как значения в mydta$v2
и уровни в mydata$v1
?
Пример: если я, например, хотел бы заказать уровни в mydata$v3
на основе наибольшего значения в mydata$v2
в пределах уровня "Полностью согласен" в mydata$v1
порядок, который я получил бы, был бы: var1
, var3
, var2
потому что значения в mydata$v2
83,1, 19,6, 11,8.
Другой пример: если я, например, хотел бы заказать уровни в mydata$v3
на основе суммы значений в mydata$v2
в уровнях "Полностью согласен" и "Согласен" в mydata$v1
заказ, который я получил бы, будет: var1
, var2
, var3
потому что значения в mydata$v2
(83,1+14,9)=98, (11,8+36,5)=48,3, (19,6+12)=31,6
Я понятия не имею, как подойти к этому сам. А также, я имею дело со многими подобными фреймами, так что код должен войти в функцию
РЕДАКТИРОВАТЬ:
В обоих примерах я получаю исходный файл data.frame ТОЛЬКО с измененным порядком уровней в mydata$v3.
Итак, в примере 1 у меня есть:
v1 v2 v3
1 Strongly agree 83.1 var1
2 Agree 14.9 var1
3 Disagree 1.5 var1
4 Strongly disagree 0.6 var1
5 Strongly agree 11.8 var2
6 Agree 36.5 var2
7 Disagree 17.7 var2
8 Strongly disagree 43.8 var2
9 Strongly agree 19.6 var3
10 Agree 12.0 var3
11 Disagree 31.6 var3
12 Strongly disagree 36.8 var3
levels(mydata$v3)
[1] "var1" "var2" "var3"
но я хочу закончить с этим.
v1 v2 v3
1 Strongly agree 83.1 var1
2 Agree 14.9 var1
3 Disagree 1.5 var1
4 Strongly disagree 0.6 var1
5 Strongly agree 11.8 var2
6 Agree 36.5 var2
7 Disagree 17.7 var2
8 Strongly disagree 43.8 var2
9 Strongly agree 19.6 var3
10 Agree 12.0 var3
11 Disagree 31.6 var3
12 Strongly disagree 36.8 var3
levels(mydata$v3)
[1] "var1" "var3" "var2"
В примере два у меня есть:
v1 v2 v3
1 Strongly agree 83.1 var1
2 Agree 14.9 var1
3 Disagree 1.5 var1
4 Strongly disagree 0.6 var1
5 Strongly agree 11.8 var2
6 Agree 36.5 var2
7 Disagree 17.7 var2
8 Strongly disagree 43.8 var2
9 Strongly agree 19.6 var3
10 Agree 12.0 var3
11 Disagree 31.6 var3
12 Strongly disagree 36.8 var3
levels(mydata$v3)
[1] "var1" "var2" "var3"
но хочу:
v1 v2 v3
1 Strongly agree 83.1 var1
2 Agree 14.9 var1
3 Disagree 1.5 var1
4 Strongly disagree 0.6 var1
5 Strongly agree 11.8 var2
6 Agree 36.5 var2
7 Disagree 17.7 var2
8 Strongly disagree 43.8 var2
9 Strongly agree 19.6 var3
10 Agree 12.0 var3
11 Disagree 31.6 var3
12 Strongly disagree 36.8 var3
levels(mydata$v3)
[1] "var1" "var2" "var3"
Обратите внимание, что в примере два то, что у меня есть, и то, что я хочу, идентично, но у меня есть много data.frames, в которых это не будет иметь место.
То, что я ищу, я думаю, это сложная версия
factor(maydata$v3, levels(mydata$v3)[EXAMPLE1: order after value in v2 within 1 level in v1 /EXAMPLE2: order after sum of value within 2 levels in v1])
1 ответ
Вот решение с aggregate
:
f <- function(mydata, v1.val) {
# Value or sum of v2 within the selected rows
sums <- aggregate(v2 ~ v3, data=mydata[mydata$v1 %in% v1.val,], FUN=sum)
# Decreasing order of the sum of v2 values, or the only v2 value, for each level of v3
ord <- order(sums$v2, decreasing=TRUE)
# Build a new factor with the proper levels and assign it to v3
fac <- factor(mydata$v3, levels=sums$v3[ord])
mydata$v3 <- fac
return(mydata)
}
Кадры данных выглядят так же, как и выше, но уровни факторов соответствуют желаемым:
> f(mydata, 'Strongly agree')$v3
[1] var1 var1 var1 var1 var2 var2 var2 var2 var3 var3 var3 var3
Levels: var1 var3 var2
> f(mydata, c('Strongly agree', 'Agree'))$v3
[1] var1 var1 var1 var1 var2 var2 var2 var2 var3 var3 var3 var3
Levels: var1 var2 var3