【问题标题】:Using reshape + cast to aggregate over multiple columns使用 reshape + cast 聚合多个列
【发布时间】:2010-05-06 14:05:55
【问题描述】:

在 R 中,我有一个数据框,其中包含 Seat(因子)、Party(因子)和 Votes(数字)列。我想创建一个包含席位、获胜方和投票份额列的摘要数据框。例如,从数据框

df <- data.frame(party=rep(c('Lab','C','LD'),times=4),
                 votes=c(1,12,2,11,3,10,4,9,5,8,6,15),
                 seat=rep(c('A','B','C','D'),each=3))

我想得到输出

  seat winner voteshare
1    A      C 0.8000000
2    B    Lab 0.4583333
3    C      C 0.5000000
4    D     LD 0.5172414

我可以弄清楚如何实现这一点。但我确信一定有更好的方法,可能是使用 Hadley Wickham 的 reshape 包的狡猾的单线。有什么建议吗?

不管怎样,我的解决方案使用了我的包中的一个函数 djwutils_2.10.zip 并按如下方式调用。但是有各种特殊情况它没有处理,所以我宁愿依赖别人的代码。

aggregateList(df, by=list(seat=seat),
              FUN=list(winner=function(x) x$party[which.max(x$votes)],
                       voteshare=function(x) max(x$votes)/sum(x$votes)))

【问题讨论】:

标签: r reshape


【解决方案1】:

Hadley 的 plyr 包可能会对您有所帮助:

ddply(df, .(seat), function(x) data.frame(winner=x[which.max(x$votes),]$party, voteshare=max(x$votes)/sum(x$votes)))

【讨论】:

  • 谢谢。这正是我想要的。
  • 或者,更简洁(很快会更快):ddply(df, .(seat), summarise, winner = party[which.max(votes)], voteshare = max(votes) / sum(votes)))
【解决方案2】:

你可能是对的,有一个狡猾的单线。我倾向于采用易于理解胜于聪明的方法,尤其是当您第一次看到某些东西时。这是更详细的替代方案。

votes_by_seat_and_party <- as.matrix(cast(df, seat ~ party, value="votes"))

   C Lab LD
A 12   1  2
B  3  11 10
C  9   4  5
D  6   8 15

seats <- rownames(votes_by_seat_and_party)
parties <- colnames(votes_by_seat_and_party)

winner_col <- apply(votes_by_seat_and_party, 1, which.max)
winners <- parties[winner_col]
voteshare_of_winner_by_seat <- apply(votes_by_seat_and_party, 1, function(x) max(x) / sum(x))

results <- data.frame(seat = seats, winner = winners, voteshare = voteshare_of_winner_by_seat)

  seat winner voteshare
1    A      C 0.8000000
2    B    Lab 0.4583333
3    C      C 0.5000000
4    D     LD 0.5172414

# Full voteshare matrix, if you're interested
total_votes_by_seat <- rowSums(votes_by_seat_and_party)
voteshare_by_seat_and_party <- votes_by_seat_and_party / total_votes_by_seat

【讨论】:

  • 您可以将缺失值(指定席位上没有特定政党的候选人)视为0NA
【解决方案3】:

好的,所以 3 个解决方案...这是另一个使用原始 R 的更紧凑的解决方案。它是 4 个稀疏代码行。我假设缺失值是 0,或者只是缺失,因为这无关紧要。我的猜测是,这将是您处理大量数据的最快代码。

#get a sum for dividing
s <- aggregate(df$votes, list(seat = df$seat), sum)
#extract the winner and seat
temp <- aggregate(df$votes, list(seat = df$seat), max)
res <- df[df$seat %in% temp$seat & df$votes %in% temp$x,]
res$votes <- res$votes / s$x

如果您愿意,可以重命名列...

res$names

(如果出现平局,这将返回错误...您将能够在临时数据框中看到它)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-19
    • 2013-12-07
    • 2012-06-06
    • 2014-03-01
    • 1970-01-01
    • 2023-04-09
    • 2012-05-10
    • 1970-01-01
    相关资源
    最近更新 更多