[英]R data frame organisation
我想分析 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
這里座位列中的數字是指划船者(因此有 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))
冗余和便利之間似乎存在權衡。 雖然在關系數據庫中會使用多個關系,但 R 社區似乎更喜歡在單個數據框中共享數據。 我相信總有辦法讓它工作,但缺乏經驗我很好奇有經驗的 R 用戶將如何組織數據。
附錄:很多答案突出了問題的重要性。 以下是將數據轉換為矩陣形式的好處:賽艇運動員在比賽中花費的總時間:一個事件時間向量和一個連接前面提到的事件和賽艇運動員的 {0,1} 值矩陣。 結果可以通過將它們相乘來獲得。
這當然是一個見仁見智的問題(完全同意@MattB)。 數據框是許多統計分析的一種非常方便的方法,但很多時候您必須對其進行轉換以適應您的目的。
您的案例以“寬格式”顯示數據框。 我認為沒有方便的方法來添加更多關於賽艇運動員的事實。 我會將其轉換為“長格式”。 在寬式中,每個划船者都有自己的划船。 而且由於賽艇運動員似乎是您的“感興趣的對象”(您的案件),這可能會使事情變得更容易。 問題“4 號槳手參加了哪些比賽?” 可以很容易地用那種形式回答。
創建一個事件表與賽艇運動員將數據融合為長格式m
,然后再轉換為適當的寬格式。 沒有理由你不能擁有多個 forms 中的數據,因此實際上沒有必要選擇最好的 forms。 如果有新數據進入,您始終可以重新生成它們。感興趣的形式實際上取決於您想用它做什么,但下面的代碼為您提供了三個 forms:
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
給予:
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
或者,使用 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)
這將是一個見仁見智的問題,部分取決於您想對該數據集提出什么樣的問題。 例如,“4 號划手參加了哪些比賽?”這個問題。 上面的格式不容易回答。
出於這個原因,我傾向於:
這將避免大多數冗余並允許相對簡單地回答大多數問題(我能想到的)。您始終可以使用 function(例如,使用dcast
)來重新創建上面顯示的表單以供人類閱讀。
沒有異議,這取決於問題。 但我懷疑在你的情況下,很多東西都會從長格式中得到解答,這也使得在需要時附加額外的賽艇運動員信息變得容易。
library(dplyr)
library(tidyr)
my_way <- pivot_longer(df, starts_with("seat"), values_to = "rower", names_to = "seat")
my_way
#> # A tibble: 48 x 5
#> time race boat seat rower
#> <dbl> <int> <dbl> <chr> <dbl>
#> 1 205. 1 1 seat1 2
#> 2 205. 1 1 seat2 6
#> 3 205. 1 1 seat3 1
#> 4 205. 1 1 seat4 5
#> 5 202. 2 1 seat1 4
#> 6 202. 2 1 seat2 5
#> 7 202. 2 1 seat3 2
#> 8 202. 2 1 seat4 7
#> 9 202. 3 1 seat1 2
#> 10 202. 3 1 seat2 6
#> # … with 38 more rows
my_way %>% group_by(rower) %>% summarise(mean(time))
#> # A tibble: 8 x 2
#> rower `mean(time)`
#> <dbl> <dbl>
#> 1 1 206.
#> 2 2 204.
#> 3 3 205.
#> 4 4 205.
#> 5 5 205.
#> 6 6 205.
#> 7 7 204.
#> 8 8 206.
my_way %>% group_by(rower, seat) %>% summarise()
#> # A tibble: 16 x 2
#> # Groups: rower [8]
#> rower seat
#> <dbl> <chr>
#> 1 1 seat1
#> 2 1 seat3
#> 3 2 seat1
#> 4 2 seat3
#> 5 3 seat1
#> 6 3 seat3
#> 7 4 seat1
#> 8 4 seat3
#> 9 5 seat2
#> 10 5 seat4
#> 11 6 seat2
#> 12 6 seat4
#> 13 7 seat2
#> 14 7 seat4
#> 15 8 seat2
#> 16 8 seat4
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.