【问题标题】:dplyr / tidyr summaries two columns into a single named list columndplyr / tidyr 将两列汇总为一个命名列表列
【发布时间】:2019-06-18 19:34:47
【问题描述】:

想象一下这个数据框:

df <- tibble(
  key = c(rep(1, 3), rep(2, 3), rep(3, 3)),
  date = rep(Sys.Date(), 9),
  hour = rep(c('00', '01', '02'), 3),
  value = rep(c(8, 9, 10), 3)
  )

我希望输出使得组摘要列是小时和值的命名列表。就好像我要为每个组执行此操作一样:

as.list(setNames(df$value[df$key == 1], df$hour[df$key == 1]))
$`00`
[1] 8

$`01`
[1] 9

$`02`
[1] 10

类似的东西,但确实有效的东西:

df %>%
  group_by(key, date) %>%
  summarise(
    daily_value = sum(value),
    hourly_values = as.list(setNames(value, hour))
    )

也可以使用nest 或类似的 tidyr 解决方案。

编辑:输出应与此处生成的相同:

outputDf <- df %>%
  group_by(key, date) %>%
  summarise(daily_value = sum(value))

outputDf$hourly_value <- list(
  as.list(setNames(df$value[df$key == 1], df$hour[df$key == 1])),
  as.list(setNames(df$value[df$key == 2], df$hour[df$key == 2])),
  as.list(setNames(df$value[df$key == 3], df$hour[df$key == 3]))
  )

outputDf
# A tibble: 3 x 4
# Groups:   key [?]
    key       date daily_value hourly_value
  <dbl>     <date>       <dbl>       <list>
1     1 2019-06-18          27   <list [3]>
2     2 2019-06-18          27   <list [3]>
3     3 2019-06-18          27   <list [3]>

outputDf$hourly_value
[[1]]
[[1]]$`00`
[1] 8

[[1]]$`01`
[1] 9

[[1]]$`02`
[1] 10


[[2]]
[[2]]$`00`
[1] 8

[[2]]$`01`
[1] 9

[[2]]$`02`
[1] 10


[[3]]
[[3]]$`00`
[1] 8

[[3]]$`01`
[1] 9

[[3]]$`02`
[1] 10

【问题讨论】:

  • 如果您提供所需输出的示例,将会很有帮助。当您说“组摘要列是小时和值的命名列表”时,不确定您在寻找什么。
  • 我不希望输出列的每个单元格都像as.list(setNames(df$value[df$key == 1], df$hour[df$key == 1])) 的输出那样。
  • 您可以使用purrr 中的map() 创建一个列表列,然后为列表列分配名称

标签: r dplyr tidyr


【解决方案1】:

我们需要用list 包装,因为summarise 期望每组返回一行。使用as.list,它将是listlength 与组的行数相同。通过将其包装为list,我们确保summarise 的长度为1

library(dplyr)  
df %>% 
   group_by(key, date) %>% 
   summarise(daily_value = sum(value), 
              hourly_values = list(as.list(setNames(value, hour))))

【讨论】:

  • 这样就行了。我原以为as.list 会返回一个列表。你能帮我理解为什么需要在另一个list 电话中换行吗?
【解决方案2】:
df <- tibble(
  key = c(rep(1, 3), rep(2, 3), rep(3, 3)),
  date = rep(Sys.Date(), 9),
  hour = rep(c('00', '01', '02'), 3),
  value = rep(c(8, 9, 10), 3)
)

df2 <- df %>% 
  group_by(key, date) %>% 
  mutate(daily_value = sum(value),
  hourly_value = as.list(value)) #create a list column

names(df2$hourly_value) <- df$hour #give names to the list column

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-15
    • 2014-06-23
    • 2016-11-15
    相关资源
    最近更新 更多