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

How to get one row per unique ID with multiple columns per values of particular column

我有一个看起来像 (A) 的数据集,我正在尝试获取 (B):

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

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

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

我已经尝试查找许多不同的东西,但在我是否应该考虑重塑、dcast 与 spread/gather 之间感到困惑...R 的新手,所以任何帮助表示赞赏!

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

首先,您应该隔离 table 中未明确表示的生日;那么你应该重塑并最终恢复生日。

使用包 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), value.var = "event",fun.aggregate = length)

一个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