如何为每个唯一 ID 获取一行,并为特定列的每个值获取多列

问题描述

我有一个类似于 (A) 的数据集,我正在尝试获取 (B):

#(A)
event <- c('A','A','B','C','D','D')
person <- c('Ann','Sally','Ryan','Ann','Ryan')
birthday <- c('1990-10-10',NA,'1985-01-01','1990-10-10','1950-04-02',NA)
data <- data.frame(event,person,birthday)

#(B)
person <- c('Ann','Ryan')
A <- c(1,1,1)
B <- c(1,1)
C <- c(0,1)
D <- c(1,1)
birthday <- c('1990-10-10','1985-01-01')
data <- data.frame(person,A,B,C,D,birthday)

基本上,我有一个活动的注册列表,可以看到参加各种活动的人。我想获得所有独特人物的列表,其中包含他们参加/未参加过的活动的专栏。我还从一些事件中获得了个人资料数据,但有些数据比其他事件的数据多 - 所以我也想保留最完整的数据(即无法从事件 D 中识别瑞安的生日,但可以从事件 B 中识别)。>

我已经尝试查找许多不同的东西,但在是否应该考虑重塑、与 dcast、与传播/收集之间感到困惑... R 的新手,因此感谢任何帮助!

编辑:附加 q - 如果有人参加了某个活动,而不是表示 1/0,如果多个活动属于同一类别,您将如何确定某人参加该类别活动的次数?例如,我也会在数据集中有名为 A1、A2 和 A3 的事件。决赛桌仍然会有一个名为 A 的列,但不是只有 1/0,如果该人没有参加 A 活动,它将显示为 0,如果该人参加了 1、2 或 3 个 A 活动,则显示为 1、2 或 3 .

解决方法

data.table 选项

dcast(
  setDT(data),person + na.omit(birthday)[match(person,person[!is.na(birthday)])] ~ event,fun = length
)

给予

   person   birthday A B C D
1:    Ann 1990-10-10 1 1 0 1
2:   Ryan 1985-01-01 1 1 0 1
3:  Sally 1950-04-02 1 0 1 1

使用 reshape 的基本 R 选项

reshape(
  transform(
    data,birthday = na.omit(birthday)[match(person,person[!is.na(birthday)])],cnt = 1
  ),direction = "wide",idvar = c("person","birthday"),timevar = "event"
)

给予

  person   birthday cnt.A cnt.B cnt.C cnt.D
1    Ann 1990-10-10     1     1    NA     1
2  Sally 1950-04-02     1    NA     1     1
3   Ryan 1985-01-01     1     1    NA     1
,

首先,您应该隔离在您的表格中没有清晰表示的生日;那么你应该重塑并最终恢复生日。

使用包 reshape2 :

birthdays <- unique(data[!is.na(data$birthday),c("person","birthday")])
reshaped <- reshape2::dcast(data,person ~ event,value.var = "event",fun.aggregate = length)
final <- merge(reshaped,birthdays)

说明:我只是告诉 reshape2::dcast 将我的 person 放入行并将 event 放入列中,并计算事件的每次出现(由聚合函数 length 产生)。

编辑:对于您的其他问题,它的工作原理相同,只需在事件变量上添加 substr() :

   reshaped <- reshape2::dcast(data,person ~ substr(event,1,1),fun.aggregate = length)