如何使用 R 中第一个 data.frame 的信息,将第二个 data.frame 的 header 作为线图的轴?

How to use the header of a second data.frame as axis of a line plot using information of a first data.frame in R?

在 R 中读取我的数据后,我有两个 R 内部变量,GoatsGoatPositions,看起来像这样:

> Goats
  GPS_No Goat_ID GoatName
1      5  660294    SIVKA
2      6  777077     MESI
3      7  660300   TONAKA
4      8  630328   ISKREA
5      9  608418    RIBEA
6     10  660290      OTA

> GoatPositions
  2020-07-13 18:00:00 2020-07-14 08:00:00 2020-07-14 18:00:00 2020-07-15 08:00:00
1                  33                  46                  NA                  44
2                  71                  59                  57                  71
3                  55                  NA                  40                  50
4                  18                  61                  24                  62
5                  53                   0                  44                   1
6                   4                  54                  54                  52

两个 R 变量的 data.frame 有更多行,变量 GoatPositions 也有更多列。

我想做的是按以下方式绘制数据:

(目前 y-axis 的标签未在任何地方指示。它将成为“位置”。)

当然,?plot描述了它的用法: 情节(x,y,类型,主要,xlab,ylab), R 中的数据引用工作方式如下: variablename[ row_conditions , column_conditions ]

因此,从中改编得到:

plot(GoatPositions[,0:3], GoatPositions[0:5,], type="l", {linelab=Goats$GoatName})

当然 {linelab=Goats$GoatName} 是占位符 pseudo-code,如果删除 {} 括号,它也不会 运行,但我从这里开始提出的问题是:

如何使用 R 中第一个 data.frame 的信息,将第二个 data.frameheader 作为线图的轴?


编辑

感谢@Eyayaw 的评论,我可以 运行 一些代码:

GoatPositionsLong <- reshape(GoatPositions, direction = 'long', timevar = 'date', varying = list(1:NCOL(GoatPositions)), times = colnames(GoatPositions), v.names = 'goat_pos')
Goats <- cbind(Goats, 1:nrow(Goats))
names(Goats)[names(Goats)=="1:nrow(Goats)"] <- "id"
GoatMerged <- merge(GoatPositionsLong, Goats, by = "id")

变量 GoatMerged 现在看起来像这样:

> GoatMerged
    id                date goat_pos GPS_No Goat_ID GoatName
1    1 2020-07-13 18:00:00       33      5  660294    SIVKA
2    1 2020-07-18 08:00:00      102      5  660294    SIVKA
...
14   2 2020-07-15 08:00:00       71      6  777077     MESI
15   2 2020-07-17 18:00:00       79      6  777077     MESI
...
27   3 2020-07-15 08:00:00       50      7  660300   TONAKA
28   3 2020-07-14 18:00:00       40      7  660300   TONAKA

共有 117 行。现在,如果我尝试绘制此图:

plot(GoatMerged$date, GoatMerged$goat_pos, type="l")

我仍然遇到错误:

Error in plot.window(...) : finite 'xlim' values necessary
Additional warnings:
1: In min(x) : no no-missing argument for min; give Inf back
2: In max(x) : no no-missing argument for max; give -Inf back

感谢@Eyayaw 的评论!

但是,现在我还想问:如何绘制现在长格式的结构化数据?


编辑 2

感谢@Eyayaw 的进一步评论,我检查了 GoatMerged$date 的 class 并进行了相应的更改:

> class(GoatMerged$date)
[1] "character"

> GoatMerged$date <- as.POSIXct(GoatMerged$date, tz="Europe/Ljubljana")

> class(GoatMerged$date)
[1] "POSIXct" "POSIXt"

> plot(GoatMerged$date, GoatMerged$goat_pos, type="l")

我得到的结果图是这样的:

这个情节的问题是它看起来不像想要的情节:

这就提出了一个问题:为什么 plot 命令会尝试读出日期的星期几并将数据绘制为时间循环 (?) 而不是单个时间点? 那么,如何以 'sequence of time points' 方式绘制 DateTime / "POSIXct" "POSIXt" 数据?


编辑 3

正如@Eyayaw 所问,这里是

的输出
> dput(GoatMerged)
structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 
5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 
7L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 
9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L), date = structure(c(1626192000, 
1626588000, 1626710400, 1626537600, 1626364800, 1626415200, 1626674400, 
1626501600, 1626242400, 1626624000, 1626328800, 1626451200, 1626278400, 
1626328800, 1626537600, 1626278400, 1626710400, 1626501600, 1626364800, 
1626674400, 1626451200, 1626192000, 1626242400, 1626624000, 1626415200, 
1626588000, 1626328800, 1626278400, 1626710400, 1626537600, 1626364800, 
1626242400, 1626674400, 1626501600, 1626451200, 1626192000, 1626624000, 
1626588000, 1626415200, 1626710400, 1626328800, 1626624000, 1626674400, 
1626537600, 1626278400, 1626501600, 1626364800, 1626242400, 1626588000, 
1626451200, 1626192000, 1626415200, 1626588000, 1626415200, 1626242400, 
1626624000, 1626364800, 1626192000, 1626451200, 1626710400, 1626537600, 
1626278400, 1626674400, 1626501600, 1626328800, 1626501600, 1626710400, 
1626451200, 1626328800, 1626674400, 1626537600, 1626415200, 1626624000, 
1626364800, 1626242400, 1626278400, 1626588000, 1626192000, 1626501600, 
1626328800, 1626278400, 1626710400, 1626451200, 1626415200, 1626242400, 
1626674400, 1626537600, 1626364800, 1626192000, 1626624000, 1626588000, 
1626328800, 1626501600, 1626278400, 1626674400, 1626710400, 1626451200, 
1626242400, 1626537600, 1626415200, 1626192000, 1626624000, 1626364800, 
1626588000, 1626624000, 1626451200, 1626588000, 1626278400, 1626674400, 
1626415200, 1626242400, 1626501600, 1626537600, 1626364800, 1626192000, 
1626328800, 1626710400), class = c("POSIXct", "POSIXt"), tzone = "Europe/Ljubljana"), 
    goat_pos = c(33L, 102L, 55L, 42L, 50L, 50L, 42L, 28L, 46L, 
    28L, 44L, 29L, NA, 71L, 79L, 57L, 88L, 86L, 78L, 78L, 51L, 
    71L, 59L, 78L, 69L, 78L, 50L, 40L, 52L, 53L, 55L, NA, 46L, 
    54L, 60L, 55L, 58L, 56L, 48L, 61L, 62L, 61L, 61L, 61L, 24L, 
    44L, 19L, 61L, 81L, 81L, 18L, 81L, 22L, 6L, 0L, 7L, 9L, 53L, 
    5L, 8L, 20L, 44L, 3L, 8L, 1L, 48L, 27L, 64L, 52L, 52L, 69L, 
    52L, 34L, 46L, 54L, 54L, 33L, 4L, 4L, 2L, 4L, 2L, 3L, 5L, 
    NA, 5L, 1L, 2L, 11L, 3L, 5L, 28L, 61L, 53L, 45L, 47L, 35L, 
    37L, 41L, 40L, 49L, 31L, 40L, 28L, 101L, 99L, 99L, 83L, 99L, 
    102L, 81L, 102L, 103L, 98L, 81L, 81L, 103L), GPS_No = c(5L, 
    5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 
    6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 
    7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 
    8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 
    9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 
    10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 
    11L, 11L, 11L, 11L, 11L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 
    12L, 12L, 12L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 13L, 13L, 
    13L, 13L, 13L, 13L, 13L, 13L, 13L), Goat_ID = c(660294L, 
    660294L, 660294L, 660294L, 660294L, 660294L, 660294L, 660294L, 
    660294L, 660294L, 660294L, 660294L, 660294L, 777077L, 777077L, 
    777077L, 777077L, 777077L, 777077L, 777077L, 777077L, 777077L, 
    777077L, 777077L, 777077L, 777077L, 660300L, 660300L, 660300L, 
    660300L, 660300L, 660300L, 660300L, 660300L, 660300L, 660300L, 
    660300L, 660300L, 660300L, 630328L, 630328L, 630328L, 630328L, 
    630328L, 630328L, 630328L, 630328L, 630328L, 630328L, 630328L, 
    630328L, 630328L, 608418L, 608418L, 608418L, 608418L, 608418L, 
    608418L, 608418L, 608418L, 608418L, 608418L, 608418L, 608418L, 
    608418L, 660290L, 660290L, 660290L, 660290L, 660290L, 660290L, 
    660290L, 660290L, 660290L, 660290L, 660290L, 660290L, 660290L, 
    611145L, 611145L, 611145L, 611145L, 611145L, 611145L, 611145L, 
    611145L, 611145L, 611145L, 611145L, 611145L, 611145L, 457088L, 
    457088L, 457088L, 457088L, 457088L, 457088L, 457088L, 457088L, 
    457088L, 457088L, 457088L, 457088L, 457088L, 611254L, 611254L, 
    611254L, 611254L, 611254L, 611254L, 611254L, 611254L, 611254L, 
    611254L, 611254L, 611254L, 611254L), GoatName = c("SIVKA", 
    "SIVKA", "SIVKA", "SIVKA", "SIVKA", "SIVKA", "SIVKA", "SIVKA", 
    "SIVKA", "SIVKA", "SIVKA", "SIVKA", "SIVKA", "MESI", "MESI", 
    "MESI", "MESI", "MESI", "MESI", "MESI", "MESI", "MESI", "MESI", 
    "MESI", "MESI", "MESI", "TONÄŒKA", "TONÄŒKA", "TONÄŒKA", 
    "TONÄŒKA", "TONÄŒKA", "TONÄŒKA", "TONÄŒKA", "TONÄŒKA", "TONÄŒKA", 
    "TONÄŒKA", "TONÄŒKA", "TONÄŒKA", "TONÄŒKA", "ISKREÅ ", "ISKREÅ ", 
    "ISKREÅ ", "ISKREÅ ", "ISKREÅ ", "ISKREÅ ", "ISKREÅ ", "ISKREÅ ", 
    "ISKREŠ", "ISKREŠ", "ISKREŠ", "ISKREŠ", "ISKREŠ", "RIBEŽ", 
    "RIBEŽ", "RIBEŽ", "RIBEŽ", "RIBEŽ", "RIBEŽ", "RIBEŽ", 
    "RIBEŽ", "RIBEŽ", "RIBEŽ", "RIBEŽ", "RIBEŽ", "RIBEŽ", 
    "OTA", "OTA", "OTA", "OTA", "OTA", "OTA", "OTA", "OTA", "OTA", 
    "OTA", "OTA", "OTA", "OTA", "ZAJKA", "ZAJKA", "ZAJKA", "ZAJKA", 
    "ZAJKA", "ZAJKA", "ZAJKA", "ZAJKA", "ZAJKA", "ZAJKA", "ZAJKA", 
    "ZAJKA", "ZAJKA", "BRINA", "BRINA", "BRINA", "BRINA", "BRINA", 
    "BRINA", "BRINA", "BRINA", "BRINA", "BRINA", "BRINA", "BRINA", 
    "BRINA", "TISA", "TISA", "TISA", "TISA", "TISA", "TISA", 
    "TISA", "TISA", "TISA", "TISA", "TISA", "TISA", "TISA"), 
    EarStatus = c("Control", "Control", "Control", "Control", 
    "Control", "Control", "Control", "Control", "Control", "Control", 
    "Control", "Control", "Control", "Short-ear", "Short-ear", 
    "Short-ear", "Short-ear", "Short-ear", "Short-ear", "Short-ear", 
    "Short-ear", "Short-ear", "Short-ear", "Short-ear", "Short-ear", 
    "Short-ear", "Control", "Control", "Control", "Control", 
    "Control", "Control", "Control", "Control", "Control", "Control", 
    "Control", "Control", "Control", "Control", "Control", "Control", 
    "Control", "Control", "Control", "Control", "Control", "Control", 
    "Control", "Control", "Control", "Control", "Control", "Control", 
    "Control", "Control", "Control", "Control", "Control", "Control", 
    "Control", "Control", "Control", "Control", "Control", "Control", 
    "Control", "Control", "Control", "Control", "Control", "Control", 
    "Control", "Control", "Control", "Control", "Control", "Control", 
    "Control", "Control", "Control", "Control", "Control", "Control", 
    "Control", "Control", "Control", "Control", "Control", "Control", 
    "Control", "Short-ear", "Short-ear", "Short-ear", "Short-ear", 
    "Short-ear", "Short-ear", "Short-ear", "Short-ear", "Short-ear", 
    "Short-ear", "Short-ear", "Short-ear", "Short-ear", "Short-ear", 
    "Short-ear", "Short-ear", "Short-ear", "Short-ear", "Short-ear", 
    "Short-ear", "Short-ear", "Short-ear", "Short-ear", "Short-ear", 
    "Short-ear", "Short-ear")), row.names = c(NA, -117L), class = "data.frame")

由于基本情节可能涉及写 for loopGoatName 着色 goat_pos,即为每个玩家的每行着色,ggplot2 会更容易。所以我们开始吧:

library(ggplot2)

ggplot(goat, aes(date, goat_pos, color = as.factor(GoatName))) + 
    geom_line() + 
    scale_x_datetime(date_breaks = '1 day') + 
    labs(color = 'Goats', y='Positions') +
    theme_classic()

output