重新设计R中加权平均值的多个相关数据帧

时间:2014-09-25 01:14:24

标签: 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和{{1} }到0),FALSE包含我想用于加权平均计算的数据。请注意,Number的结构与TZWeight不同,但重要 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我的数据框mergeWeight,以便我可以使用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.namesWeightNumbermergeTime.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")

1 个答案:

答案 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