一个看似简单的问题让我很忙。
我有一个数据框:
> df1
Name Score
1 Ben 1
2 Ben 2
3 John 1
4 John 2
5 John 3
我想像这样创建一个表的摘要:
> df2
Name Score_1 Score_2 Score_3
1 Ben 1 1 0
2 John 1 1 1
所以df2必须(i)只显示唯一的“姓名”和(ii)根据“得分”中的独特因素创建列,以及(iii)计算一个人收到所述得分的次数。
我尝试过:
df2 <- ddply(df1, c("Name"), summarise
,Score_1 = sum(df1$Score == 1)
,Score_2 = sum(df1$Score == 2)
,Score_3 = sum(df1$Score == 3))
产生:
Name Score_1 Score_2 Score_3
1 Ben 2 2 1
2 John 2 2 1
所以我的尝试错误地计算所有出现而不是计算“每组”
修改
根据评论,还试过reshape
(可能只是做错了):
> reshape(df1, idvar = "Name", timevar = "Score", direction = "wide")
Name
1 Ben
3 John
首先,“得分”栏目缺失但比这更糟糕,根据我对reshape
的研究,我不相信我会得到每个数因素,这是重点。
答案 0 :(得分:3)
您只需对代码稍作修改即可。您应该使用.(Name)
代替c("Name")
:
ddply(df1, .(Name), summarise,
Score_1 = sum(Score == 1),
Score_2 = sum(Score == 2),
Score_3 = sum(Score == 3))
给出:
Name Score_1 Score_2 Score_3
1 Ben 1 1 0
2 John 1 1 1
其他可能性包括:
1。 table(df1)
正如comments中提到的@alexis_laz,这给出了:
> table(df1)
Score
Name 1 2 3
Ben 1 1 0
John 1 1 1
2。 reshape2 包的dcast
功能(或 data.table 具有相同的dcast
功能):
library(reshape2) # or library(data.table)
dcast(df1, Name ~ paste0("Score_", Score), fun.aggregate = length)
给出:
Name Score_1 Score_2 Score_3
1 Ben 1 1 0
2 John 1 1 1
答案 1 :(得分:2)
我们可以使用dplyr/tidyr
library(dplyr)
library(tidyr)
df1 %>%
group_by(Name) %>%
mutate(n=1, Score= paste('Score', Score, sep='_')) %>%
spread(Score, n, fill=0)
# Name Score_1 Score_2 Score_3
# (chr) (dbl) (dbl) (dbl)
#1 Ben 1 1 0
#2 John 1 1 1