在R中,我有一个数据框,其中包含Seat(factor),Party(factor)和Votes(numeric)列。我想创建一个摘要数据框,其中包含Seat,Winning party和Vote share的列。例如,从数据框
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)))
答案 0 :(得分:11)
Hadley的plyr包可以帮助你:
ddply(df, .(seat), function(x) data.frame(winner=x[which.max(x$votes),]$party, voteshare=max(x$votes)/sum(x$votes)))
答案 1 :(得分:3)
你可能是对的,有一个狡猾的单行。我倾向于赞成可理解的方法比聪明方法更好,尤其是当你第一次看到某些东西时。这是更冗长的替代方案。
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
答案 2 :(得分:2)
好的,所以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&lt; - c('party','voteshare','winner')
(如果出现平局,这将返回错误...您将能够在临时数据框中看到它)