Я пытаюсь вычислить взвешенные средние значения из сложного набора данных, которые хранятся в списке. Здесь намного упрощена примерИзмените несколько связанных фреймов для взвешенных средних значений в R
dfs <- structure(list(TZ = structure(list(row.names = c(168L, 302L),
type = c(1.5, 25.35), zone = c(43.53, 87.65)), .Names = c("row.names",
"type", "zone"), class = "data.frame", row.names = c(NA, -2L)),
Weight = structure(list(row.names = c(168L, 302L), `1` = c(TRUE,
FALSE), `2` = c(TRUE, TRUE)), .Names = c("row.names", "1",
"2"), class = "data.frame", row.names = c(NA, -2L)), Number = structure(list(
row.names = c(168L, 302L), `1` = c(6L, 9L), `2` = c(8L,
6L)), .Names = c("row.names", "1", "2"), class = "data.frame", row.names = c(NA,
-2L))), .Names = c("TZ", "Weight", "Number"))
, где TZ
служит в качестве классификатора/идентификатор данных, Weight
содержит веса для использования в weighted.mean
(мне нужно преобразовать TRUE
1 и FALSE
до 0), и Number
содержит данные, которые я хочу использовать для расчета средневзвешенных значений. Отметим, что структура отличается от Weight
и Number
, но важноrow.names
согласовано во всех кадрах данных, и именно так я могу связать данные между кадром данных. Мои реальные данные содержат ряд дополнительных фреймов данных, для которых я хочу выполнять те же операции (они согласуются друг с другом и с этим простым примером).
В результате я "м пытаюсь достичь
result <- structure(list(row.names = c(168L, 302L), type = c(1.5, 23.35
), zone = c(43.53, 87.65), Num.Wht = c(7L, 6L)), .Names = c("row.names",
"type", "zone", "Num.Wht"), class = "data.frame", row.names = c(NA,
-2L))
row.names type zone Num.Wht
1 168 1.50 43.53 7
2 302 23.35 87.65 6
где Num.Wht
является средневзвешенное Number
взвешенных по Weight
(после преобразования в 1s и 0s). Обратите внимание, что в моих реальных данных, у меня будет много дополнительные dataframes, и, таким образом, столбцы, содержащие средневзвешенных.
Можно ли рекомендовать хорошую стратегию для производства? Я думал в первую melt
затем merge
мои dataframes Weight
и Number
, так что я мог, то и се weighted.mean
library(reshape2)
test1 <- melt(dfs$Weight, id="row.names")
colnames(test1)[2:3] <- c("Time", "Weight")
test2 <- melt(dfs$Number, id="row.names")
colnames(test2)[2:3] <- c("Time", "Number")
Однако при использовании
test <- merge(test1, test2, by.x="row.names", by.y="row.names")
или
test <- merge(test1, test2, by.x="test1$row.names", by.y="test$2row.names")
Я получаю сообщение об ошибке
Error in fix.by(by.x, x) : 'by' must specify a uniquely valid column
Я также попробовал первые merge
в dataframes до переформирования, например
dat <- merge(dfs$TZ, dfs$Weight, by.x="row.names", by.y="row.names")
Однако это дает ту же ошибку. (Любопытно, что это действительно работает в моих реальных данных.)
Я также попытался изменить row.names
в Weight
и Number
, merge
дает мне различные столбцы для Time.x
и Time.y
colnames(test1) <- c("Row.names", "Time", "Weight")
colnames(test2) <- c("Row.names", "Time", "Number")
test <- merge(test1, test2, by.x="Row.names", by.y="Row.names")
Можно ли рекомендовать лучший способ для достижения желаемого результата? После того, как я могу правильно сделать это, я планирую сделать взвешенные средства, используя что-то вроде
# convert weight to 1 and 0
test$Weight <- test$Weight*1
lapply(dfs,function(d) ddply(d, .(Time), summarize, Num.Wht=weighted.mean(test$Number,test$Weight)))
Я думаю, что некоторые из ваших проблем возникает из-за того, что вызов ' merge' с 'by =" row.names "' предполагается использовать имена ростов, а не столбцы с именем '' row.names''. –