R 数据帧组织
我想分析一系列R赛艇比赛,每个赛艇有4名赛艇手,两两比赛。我想知道在数据帧中表示这一点的最佳方法。我目前有12个计时项目,2个这样的项目构成了两艘船之间的比赛R 数据帧组织,r,dataframe,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
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
在这里,座位栏中的数字指的是赛艇运动员(因此有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))
df这将是一个意见问题,部分取决于您希望对该数据集提出什么样的问题。例如,“4号赛艇手参加了哪些比赛?”这个问题不容易用上面的格式回答
因此,我倾向于:
- 一张比赛表格,很像你的,但是没有席位*栏李>
- 一张赛艇员表,可保存其他详细信息(姓名、体重等);及
- 一个连接这两者的表格,每场比赛每个划手一行
这将避免大多数冗余,并允许大多数问题(我能想到!)得到相对直接的回答。您始终可以使用一个函数(例如,使用dcast
)重新创建上面显示的表单,以便于人类阅读。这当然是一个意见问题(完全同意@MattB)。对于许多统计分析来说,数据帧是一种非常方便的方法,但很多时候,您必须对其进行转换以满足您的目的
您的案例以“宽格式”显示数据帧。我看不出有什么方便的方法来补充更多关于赛艇运动员的事实。我会把它转换成“长格式”。在宽版中,每个划手都有自己的一排。而且因为划船者似乎是你的“兴趣对象”(你的案例),这可能会让事情变得更容易。“4号赛艇运动员参加了哪些比赛?”这个问题可以用这个表格很容易地回答。创建一个事件与赛艇运动员的表格,将数据分解成长格式m
,然后再转换成适当的宽格式。您没有理由不能以多种形式保存数据,因此确实没有必要选择最佳形式。如果收到新数据,您始终可以重新生成它们。兴趣的形式实际上取决于你想用它做什么,但下面的代码给出了三种形式:
原始宽格式df
长格式m
,可用于回归、箱线图等
lm(time ~ factor(rower) + 0, m)
boxplot(time ~ boat, m)
修订后的宽格式df2
如果存在特定于划行者的属性,则这些属性可以存储在单独的数据框中,每个划行者一行,每个属性一列,并且根据您要执行的操作,如果您想在回归中使用这些属性,可以使用merge
将它们与m
合并
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
或者,对于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)
库(dplyr)
图书馆(tidyr)
m%
枢轴长度(-(1:3),名称到=“座椅”,值到=“划船者”)
df2%
枢轴宽度(1:3,名称从=划船者,值从=划船者,名称排序=真)
没有异议,这取决于问题。但我怀疑在你的情况下,很多问题都会从长格式中得到解答,这也会使你在需要的时候很容易附加额外的赛艇员信息
库(dplyr)
图书馆(tidyr)
我的方式:48 x 5
#>计时赛艇艇员
#>
#> 1 205. 1座1 2
#> 2 205. 1座2 6
#> 3 205. 1座3 1
#> 4 205. 1座4 5
#> 5 202. 2 1座1 4
#> 6 202. 2 1座2 5
#> 7 202. 2 1座3 2
#> 8 202. 2 1座4 7
#> 9 202. 3 1座1 2
#> 10 202. 3 1座2 6
#>#…还有38行
我的方式%>%按(划船者)分组%>%总结(平均(时间))
#>#A tibble:8 x 2
#>划手平均(时间)`
#>
#> 1 1 206.
#> 2 2 204.
#> 3 3 205.
#> 4 4 205.
#> 5 5 205.
#> 6 6 205.
#> 7 7 204.
#> 8 8 206.
我的方式%>%组员(划船者,座位)%>%总结()
#>#A tibble:16 x 2
#>#组别:赛艇运动员[8]
#>赛艇座椅
#>
#>1座1
#>2 1座3
#>3 2座1
#>4 2座3
#>5 3座1
#>6 3座3
#>7 4座1
#>8 4座3
#>9.5座2
#>10 5座4
#>11 6座2
#>12 6座4
#>13 7座2
#>14 7座4
#>15 8座2
#>16 8座4
谢谢。这很像我在数据库中组织的一样,但注意到R中的数据集通常不是标准化的,或者是从单个CSV文件读取的。这可能是真的——如果要求从单个.CSV文件读取所有数据,那么这就增加了宽格式参数的权重。根据我的经验,当R中的数据被考虑和设计时,它看起来很像是一个好的数据库设计“…12x8矩阵,它捕获了哪个赛艇运动员参加了哪个比赛。”使用的一种方法是:df%>%pivot\u更长(cols=start\u with(“seat”)、names\u to=“seat”、values\u to=“rower”)%%>%pivot\u更宽(names\u from=rower、values\u from=seat)
。您也可以使用use,它具有类似的功能,包括MattB推荐的dcast。在长格式中,您可以使用my_way%>%groupby(rower)%%>%summary(Total_row_time=sum(time))快速获得每个划船者的总划船时间
如果这是您需要回答的问题,请大家在这里演示R快速转换数据的能力-谢谢。我知道melt
(来自tidyr
),但不知道dcast
;管道符号%>%
在函数式编程中很常见。正如您前面所说的,最初如何加载数据实际上并不重要,而您所拥有的可能是一个很好的选择,r的力量在于旋转事物。我不会太担心效率低下的复制品
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)