【问题标题】:How to get one row per unique ID with multiple columns per values of particular column如何为每个唯一 ID 获取一行,每个特定列的值具有多列
【发布时间】:2021-02-15 14:19:18
【问题描述】:

我有一个看起来像 (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)

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

我已经尝试查找许多不同的东西,但是对于我是否应该关注重塑、dcast、传播/收集......对于 R 来说是新手,因此不胜感激!

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

【问题讨论】:

    标签: r reshape tidyr spread dcast


    【解决方案1】:

    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
    

    【讨论】:

    • 非常感谢!效果也很好,自从他第一次发布以来就接受了 Leon 的回答,但很感激
    【解决方案2】:

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

    使用包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)
    

    【讨论】:

    • 谢谢,我会试试这个!有没有一种快速的方法来隔离和重新合并“其他信息”? IE。我只为这个样本包括了生日,但我实际上收集了很多个人资料数据,所以数据集实际上要大得多(例如,有事件、姓名、生日、姓名、电话等......)
    • 如果您不想先隔离此数据,则使用此方法您将不得不“填补空白”。换句话说,您需要将 NA 替换为适当的值;然后,您可以将生日添加到行中: reshape
    猜你喜欢
    • 2015-09-03
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    相关资源
    最近更新 更多