Средневзвешенные значения для всех столбцов в R data.frame

У меня есть data.frame 32x43 с именем "allg2", и я воссоздал небольшую его часть здесь как 5x5 для простоты:

gneiss mylonite syenite sedimentary Catg
0      3        4       0           -105.7
2      90       1       0           -99.7
15     51       0       0           -95.25
6      0        0       0           -90.5
0      3        9       0           -85.45

В соответствии с запросом пример расчета: столбец «гнейс» будет равен wm=(0/21*-105,7)+(2/21*-99,7)+(15/21*-95,25)+(6/21*-90,5). )+(0/21*-85,45)

Я хотел бы взвешенное среднее значение для каждого столбца (с интересующими значениями в Catg и каждым столбцом в качестве весов для этого столбца), но каждое решение, которое я могу найти, зависит от кодирования во всех именах столбцов. Можно ли это сделать без такого списка? Примечание. Я только что понял, что все время переворачивал веса и значения для взвешивания. Мои попытки:

wm=allg2[,lapply(.SD,weighted.mean,w=Catg),by=list(allg2[1,])]
Error: unused argument (by = list(allg2[1, ]))

Я нашел эту идею в этой теме и попытался адаптировать ее к моей ситуации. . Разве это не выбор имен столбцов, потому что они не являются истинной строкой? Я действительно не знаю, что это делает, и я попытался удалить часть by=, что дает ошибку

 Error in lapply(.SD, weighted.mean, w = Catg) : object '.SD' not found

Другая попытка была основана на этой теме. «Catg» находится в 43-м столбце, поэтому я попытался организовать строку следующим образом:

wm=apply(allg2, 2, function(x) weighted.mean(x[,43], x[,1:42]))
Error in x[, 43] : incorrect number of dimensions

Я действительно не понимаю эту ошибку, потому что мой столбец весов должен быть в [,43].

Я также пробовал:

mallg=data.matrix(allg2)
wm=colWeightedMeans(mallg,allg2$Catg)
Error in colWeightedMeans.matrix(mallg, allg2$Catg) : Argument 'w' has negative weights.

Я действительно в недоумении здесь. Я делаю небольшую ошибку или я делаю это совершенно неправильно?


person Riebeckite    schedule 30.11.2013    source источник
comment
Вы отредактировали вопрос, это слишком запутанно. Не могли бы вы сделать взвешенное среднее вручную, чтобы мы могли понять вашу проблему?   -  person juliohm    schedule 30.11.2013
comment
С удовольствием, извините за путаницу. Столбец «гнейс» будет следующим: wm=(0/21*-105,7)+(2/21*-99,7)+(15/21*-95,25)+(6/21*-90,5)+(0/21* -85,45)   -  person Riebeckite    schedule 30.11.2013
comment
Вы должны понимать, что кадры данных НЕ совпадают с объектами data.table. Вы используете код data.table для фреймов данных в своей первой ошибочной попытке, и это просто не способ добиться успеха.   -  person IRTFM    schedule 30.11.2013
comment
Если 21 — это сумма элементов в Catg, то мой ответ остается в силе.   -  person juliohm    schedule 30.11.2013
comment
@juliohm, 21 - это сумма элементов в «гнейсе».   -  person Riebeckite    schedule 30.11.2013


Ответы (3)


Предполагая, что ваши веса находятся в последнем столбце:

ll <- lapply(df[ , -ncol(df)], weighted.mean,  w = df$Catg)
ll
# $gneiss
# [1] 4.555497
# 
# $mylonite
# [1] 30.22283
# 
# $syenite
# [1] 2.709924
# 
# $sedimentary
# [1] 0

Изменить: после вашего комментария вам нужно сделать следующее:

lapply(df[ , -ncol(df)], weighted.mean, x = df$Catg)
person Henrik    schedule 30.11.2013
comment
Я только что понял, что задал неправильный вопрос; у меня он перевернулся. Веса указаны в каждом соответствующем столбце, а интересующие значения — только в последнем столбце. Я отредактирую исходный вопрос, но как мне адаптировать его к этой ситуации? - person Riebeckite; 30.11.2013
comment
Просто сделайте минимальный пример, который фиксирует все соответствующие характеристики ваших данных - не больше и не меньше - например. два минерала со столбцами исходных значений и веса в соответствующем порядке. Затем мы посмотрим, как мы соответствующим образом обновим ответы. - person Henrik; 30.11.2013
comment
@DWin, это сработало отлично! Благодарю вас! Редактировать: я также только что понял, что вы решили мою последнюю проблему с R. - person Riebeckite; 30.11.2013

dt[,lapply(.SD,weighted.mean,w=Catg)]
apply(dt, 2, function(col) weighted.mean(x = col, w = dt[,Catg]))

Я думаю, вам нужно лучше понимать аргументы каждой функции.

Обновление после того, как OP изменил вопрос, чтобы веса были в столбцах, а значение было в Catg - dt[,lapply(.SD,weighted.mean,x=Catg)]; apply(dt, 2, function(col) weighted.mean(w = col, x = dt[,Catg]))

person TheComeOnMan    schedule 30.11.2013
comment
Я новичок в R, поэтому я все еще борюсь с терминологией. Кроме того, я понял, что задал неправильный вопрос, и обновил его как таковой: интересующие значения находятся в последнем столбце, а соответствующие веса - в других столбцах. - person Riebeckite; 30.11.2013
comment
Просто перевернул аргументы в конструкциях :) - person TheComeOnMan; 30.11.2013
comment
Это выглядит многообещающе. Однако я получаю сообщение об ошибке в lapply(.SD, weighted.mean, w = Catg): объект '.SD' не найден - person Riebeckite; 30.11.2013
comment
Я не думаю, что ОП понимает, что dataframes != data.tables. - person IRTFM; 30.11.2013
comment
Спасибо @DWin :). ОП, добро пожаловать в R. Возможно, вы захотите сделать install.packages('data.table'); library(data.table); dt <- data.table(dt), прежде чем пробовать эти конструкции. Таблицы данных — это не то же самое, что фреймы данных, таблицы данных гораздо более эффективны с точки зрения памяти и скорости по сравнению с фреймами данных. Я настоятельно рекомендую вам поискать таблицы данных в Интернете и попробовать их использовать. - person TheComeOnMan; 30.11.2013

Я новичок в R, но почему бы и нет:

sapply(allg2[,-ncol(allg2)], weighted.mean, allg2$Catg)
person juliohm    schedule 30.11.2013