如何为每个唯一 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
我有一个看起来像 (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
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