R 数据框组织

Chr*_*dig 12 r dataframe

我想分析 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)
  1. 为了提取赛艇运动员和赛事之间的关系,以不同的方式组织它会更好吗?
  2. 在单独的数据框中捕获有关赛艇运动员的其他信息(例如他们的体重、年龄)是否自然,还是将所有内容保存在一个数据框中更好(如何?)。

似乎在冗余和便利之间有一个权衡。而在关系数据库中,人们会使用多个关系,但 R 社区似乎更喜欢在单个数据框中共享数据。我确信总有一种方法可以使它工作,但缺乏经验我很好奇有经验的 R 用户将如何组织数据。

附录:很多答案都强调了问题的重要性。以下是将数据转化为矩阵形式的好处:赛艇运动员在比赛中花费的总时间:事件时间向量和连接前面提到的事件和赛艇运动员的 {0,1} 值矩阵。可以通过将它们相乘来获得结果。

Jan*_*Jan 6

这当然是一个意见问题(完全同意@MattB)。数据框是许多统计分析的一种非常方便的方法,但很多时候您必须转换它们以适合您的目的。

您的案例以“宽格式”显示数据框。我认为没有方便的方法可以添加更多关于赛艇运动员的事实。我会将其转换为“长格式”。在宽幅形式中,每个赛艇运动员都有自己的行。而且由于赛艇运动员似乎是您的“感兴趣的对象”(您的案例),这可能会使事情变得更容易。问题“赛艇4参加了哪些比赛?” 用那个表格可以很容易地回答。


G. *_*eck 5

创建一个事件表与赛艇运动员将数据融合为长格式m,然后再恢复为适当的宽格式。没有理由您不能拥有多种形式的数据,因此实际上没有必要选择最佳形式。如果有新数据进来,你总是可以重新生成它们。感兴趣的形式实际上取决于你想用它做什么,但下面的代码为你提供了三种形式:

  1. 原始的宽形式df
  2. m可能对回归、箱线图等有用的长形式。例如

    lm(time ~ factor(rower) + 0, m)
    boxplot(time ~ boat, m)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 修改后的宽表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)