我想分析 R 中的一系列赛艇比赛,其中每艘有 4 名赛艇运动员成对比赛。我想知道在数据框中表示它的最佳方式。我目前有 12 个定时事件,其中 2 个这样的事件构成了两艘船之间的比赛。
time race boat seat1 seat2 seat3 seat4
1 204.98 1 1 2 6 1 5
2 202.49 2 1 4 5 2 7
3 202.27 3 1 2 6 3 7
4 206.48 4 1 1 7 2 8
5 204.85 5 1 4 8 2 6
6 204.93 6 1 2 8 3 5
7 204.91 1 2 3 7 4 8
8 207.40 2 2 1 8 3 6
9 207.62 3 2 1 5 4 8
10 203.41 4 2 3 5 4 6
11 205.04 5 2 3 7 1 5
12 204.96 6 2 4 6 1 7
Run Code Online (Sandbox Code Playgroud)
此处座位栏中的数字指的是划船者(因此有 8 个),但使用名称或字母会更自然。我需要提取一个 12x8 矩阵来捕获哪个赛艇运动员参加了哪个事件。
下面的代码构建了上面的数据框:
df <- data.frame (
time = c(204.98, 202.49, 202.27, 206.48, 204.85, 204.93,
204.91, 207.40, 207.62, 203.41, 205.04, 204.96),
race = append(1:6, 1:6),
boat = append(rep(1,6),rep(2,6)),
seat1 = c(2,4,2,1,4,2, 3,1,1,3,3,4),
seat2 = c(6,5,6,7,8,8, 7,8,5,5,7,6),
seat3 = c(1,2,3,2,2,3, 4,3,4,4,1,1),
seat4 = c(5,7,7,8,6,5, 8,6,8,6,5,7))
Run Code Online (Sandbox Code Playgroud)
似乎在冗余和便利之间有一个权衡。而在关系数据库中,人们会使用多个关系,但 R 社区似乎更喜欢在单个数据框中共享数据。我确信总有一种方法可以使它工作,但缺乏经验我很好奇有经验的 R 用户将如何组织数据。
附录:很多答案都强调了问题的重要性。以下是将数据转化为矩阵形式的好处:赛艇运动员在比赛中花费的总时间:事件时间向量和连接前面提到的事件和赛艇运动员的 {0,1} 值矩阵。可以通过将它们相乘来获得结果。
这当然是一个意见问题(完全同意@MattB)。数据框是许多统计分析的一种非常方便的方法,但很多时候您必须转换它们以适合您的目的。
您的案例以“宽格式”显示数据框。我认为没有方便的方法可以添加更多关于赛艇运动员的事实。我会将其转换为“长格式”。在宽幅形式中,每个赛艇运动员都有自己的行。而且由于赛艇运动员似乎是您的“感兴趣的对象”(您的案例),这可能会使事情变得更容易。问题“赛艇4参加了哪些比赛?” 用那个表格可以很容易地回答。
创建一个事件表与赛艇运动员将数据融合为长格式m,然后再恢复为适当的宽格式。没有理由您不能拥有多种形式的数据,因此实际上没有必要选择最佳形式。如果有新数据进来,你总是可以重新生成它们。感兴趣的形式实际上取决于你想用它做什么,但下面的代码为你提供了三种形式:
df,m可能对回归、箱线图等有用的长形式。例如
lm(time ~ factor(rower) + 0, m)
boxplot(time ~ boat, m)
Run Code Online (Sandbox Code Playgroud)修改后的宽表df2。
如果存在划船器特定的属性,那么这些属性可以存储在一个单独的数据框中,每个划船器一行,每个属性一列,如果你想在回归中使用这些属性,可以根据你想要做的事情与musing合并merge,说.
library(data.table)
m <- melt(as.data.table(df), id = 1:3, value.name = "rower")
df2 <- dcast(data = m, time + race + boat ~ rower, value.var = "rower")
setkey(df2, boat, race) # sort
df2
Run Code Online (Sandbox Code Playgroud)
给予:
time race boat 1 2 3 4 5 6 7 8
1: 204.98 1 1 1 2 NA NA 5 6 NA NA
2: 202.49 2 1 NA 2 NA 4 5 NA 7 NA
3: 202.27 3 1 NA 2 3 NA NA 6 7 NA
4: 206.48 4 1 1 2 NA NA NA NA 7 8
5: 204.85 5 1 NA 2 NA 4 NA 6 NA 8
6: 204.93 6 1 NA 2 3 NA 5 NA NA 8
7: 204.91 1 2 NA NA 3 4 NA NA 7 8
8: 207.40 2 2 1 NA 3 NA NA 6 NA 8
9: 207.62 3 2 1 NA NA 4 5 NA NA 8
10: 203.41 4 2 NA NA 3 4 5 6 NA NA
11: 205.04 5 2 1 NA 3 NA 5 NA 7 NA
12: 204.96 6 2 1 NA NA 4 NA 6 7 NA
Run Code Online (Sandbox Code Playgroud)
或者,使用 dplyr/tidyr:
library(dplyr)
library(tidyr)
m <- df %>%
pivot_longer(-(1:3), names_to = "seat", values_to = "rower")
df2 <- m %>%
pivot_wider(1:3, names_from = rower, values_from = rower, names_sort = TRUE)
Run Code Online (Sandbox Code Playgroud)