我试图从存储在列表中的一组复杂数据帧中计算加权平均值。这是一个简化的例子
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和{{1} }到0),FALSE
包含我想用于加权平均计算的数据。请注意,Number
的结构与TZ
和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
(转换为1和0后)。请注意,在我的实际数据中,我将有许多其他数据帧,因此列包含加权平均值。
有人可以推荐一个好的策略来继续吗?我想先Weight
然后melt
我的数据框merge
和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
但是这会产生同样的错误。 (奇怪的是,这确实适用于我的真实数据。)
我还尝试更改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")
答案 0 :(得分:0)
Thomas,合并的问题是data.frames已经有row.names
属性,所以当你还有一个名为row.names
的列时,它不知道要选择哪一个合并(因此消息&#39; by&#39;必须指定唯一有效的列)。
因此,更改所有列&#34; row.names&#34;到&#34; id&#34;为了避免名称冲突,你可以这样做:
#renaming columns
dfs <- lapply(dfs, function(df){names(df)[1]<- "id";df})
# merging all dfs
merged_dfs <- Reduce(function(x,y) merge(x,y, by="id"), dfs)
# calculating weighted average
merged_dfs$Num.Wht <- apply(merged_dfs[,4:7], 1,
function(x) weighted.mean(x[3:4], as.numeric(x[1:2])))
# getting the end result you want
result <- merged_dfs[,-c(4:7)]
result
id type zone Num.Wht
1 168 1.50 43.53 7
2 302 25.35 87.65 6