从因子和计数创建列

时间:2016-02-01 09:04:34

标签: r plyr

一个看似简单的问题让我很忙。

我有一个数据框:

> 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的研究,我不相信我会得到每个因素,这是重点。

2 个答案:

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