【问题标题】:Spread/ Gather Error: Must supply a symbol or a string as argument传播/收集错误:必须提供符号或字符串作为参数
【发布时间】:2019-09-10 00:24:16
【问题描述】:

我已经传播数据(df)


       Timestamp    area    count   type
2019-08-28 00:30:00 area1     4     A
2019-08-28 00:30:01 area1     1     B
2019-08-28 00:30:02 area1     8     C
2019-08-28 00:30:03 area2     8     A
2019-08-28 00:30:04 area2     1     B
2019-08-28 00:30:04 area2     8     C
2019-08-28 00:30:06 area3     18    A

进入

      Timestamp       area    A    B    C


  2019-08-28 00:30:00 area1   4   NA  NA
  2019-08-28 00:30:01 area1   NA  NA  1
  2019-08-28 00:30:02 area1   NA  8   NA
  2019-08-28 00:30:03 area2   8   NA  NA
  2019-08-28 00:30:04 area2   NA  NA  1
  2019-08-28 00:30:04 area2   NA  8   NA
  2019-08-28 00:30:06 area3   18  NA  NA

使用代码

 df %>%
group_by(Timestamp, area) %>%
  spread(type, count)

然后,我想将同一区域的相邻行合并,使表格看起来像这样

        Timestamp     area    A    B    C
      <S3: POSIXct>   <chr>  <dbl><dbl><dbl>

  2019-08-28 00:30:00 area1   4   8   1


  2019-08-28 00:30:03 area2   8   8   1


  2019-08-28 00:30:06 area3   18  ... ...
.
.

我用过代码

df %>%
  gather(type, count,-area) %>%
  group_by(type) %>%
  mutate(Rank = dense_rank(type), 
         RankOrder = paste0("ord_", row_number())) %>%
  spread(type) %>%
  spread(RankOrder, Rank) %>%
  summarise_all(funs(.[which(!is.na(.))]))

但我得到了错误

eval_tidy(enquo(var), var_env) 中的错误:对象“未找到”。

要强调的一点:

每天都会重复记录数据,即。 area 每天都会重复。因此我们需要按天分组(不是日期时间,我只想提取日期)然后按区域分组我猜?但我不知道该怎么做。

最终目标是绘制type中各个元素之间的相关图。

请告诉我如何做到这一点。非常感谢。

【问题讨论】:

    标签: r dplyr tidyr


    【解决方案1】:

    以下方法的工作原理是将数据保持为长格式,直到您想在最后以宽格式查看它。基本做法是:

    library(dplyr)
    library(tidyr)
    library(lubridate)
    
    df <- tribble(
    ~Timestamp, ~area, ~count, ~type,
    "2019-08-28 00:30:00", "area1", 4, "A",
    "2019-08-28 00:30:01", "area1", 1, "B",
    "2019-08-28 00:30:02", "area1", 8, "C",
    "2019-08-28 00:30:03", "area2", 8, "A",
    "2019-08-28 00:30:04", "area2", 1, "B",
    "2019-08-28 00:30:04", "area2", 8, "C",
    "2019-08-28 00:30:06", "area3", 18, "A")
    
    df$Timestamp <- ymd_hms(df$Timestamp)
    df$date <- ymd_hms(df$Timestamp) %>% date()
    df$area <- factor(df$area)
    df$type <- factor(df$type)
    
    df %>%
      group_by(date, area, type) %>%
      summarize(count = sum(count)) %>%
      spread(key = type, value = count)
    
    # # A tibble: 3 x 5
    # # Groups:   date, area [3]
    # date       area      A     B     C
    # <date>     <fct> <dbl> <dbl> <dbl>
    # 2019-08-28 area1     4     1     8
    # 2019-08-28 area2     8     1     8
    # 2019-08-28 area3    18    NA    NA
    

    【讨论】:

    • 感谢您的回答。我忘了提到数据每天都会重复。我们也可以考虑到这一点吗?我已经编辑了这个问题。谢谢!
    • @Harper 我已经编辑了我的代码,以便在计算总和之前按日期、区域和类型对数据进行分组。这只是删除时间信息。
    • 非常感谢Gregory,我会试试看
    【解决方案2】:

    我们可以首先将数据spread 转换为宽格式,对于每个area,如果列中的所有值都是NA,我们返回NA,或者返回第一个非NA 值。

    library(dplyr)
    
    df %>%
      tidyr::spread(type, count) %>%
      group_by(area) %>%
      summarise_all(~if (all(is.na(.))) NA else first(.[!is.na(.)]))
    
    #  area  Timestamp               A     B     C
    #  <fct> <dttm>              <int> <int> <int>
    #1 area1 2019-08-28 00:30:00     4     1     8
    #2 area2 2019-08-28 00:30:03     8     1     8
    #3 area3 2019-08-28 00:30:06    18    NA    NA
    

    数据

    df <- structure(list(Timestamp = structure(c(1566923400, 1566923401, 
    1566923402, 1566923403, 1566923404, 1566923404, 1566923406), class = c("POSIXct", 
    "POSIXt"), tzone = ""), area = structure(c(1L, 1L, 1L, 2L, 2L, 
    2L, 3L), .Label = c("area1", "area2", "area3"), class = "factor"), 
    count = c(4L, 1L, 8L, 8L, 1L, 8L, 18L), type = structure(c(1L, 
    2L, 3L, 1L, 2L, 3L, 1L), .Label = c("A", "B", "C"), class = "factor")), 
    row.names = c(NA, -7L), class = "data.frame")
    

    【讨论】:

    • 感谢您的回答。我忘了提到数据每天都会重复。我们也可以考虑到这一点吗?我已经编辑了这个问题。谢谢!
    • @Harper 你能试试df %&gt;% mutate(Date = as.Date(Timestamp)) %&gt;% tidyr::spread(type, count) %&gt;% group_by(area, Date) %&gt;% summarise_all(~if (all(is.na(.))) NA else first(.[!is.na(.)]))
    • 嗨 Ronak 我确实尝试过,但不知何故它遗漏了一年的数据(两年内)。你知道原因吗?
    • @Harper 我不知道为什么会这样。一个可重现的例子可能会有所帮助。
    猜你喜欢
    • 2019-06-21
    • 2020-11-30
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 1970-01-01
    • 2020-12-01
    • 1970-01-01
    • 2022-07-14
    相关资源
    最近更新 更多