【问题标题】:In a 'summarise(data, lhs = rhs)' call: is there no way to transfer to lhs the attributes of rhs?在 'summarise(data, lhs = rhs)' 调用中:有没有办法将 rhs 的属性转移到 lhs?
【发布时间】:2021-07-19 08:02:18
【问题描述】:

以下几行突出了该问题。属性在许多情况下会转移,但不是在最后一种情况下,这是一个常见的“总结”用例。非常感谢任何帮助!

suppressWarnings(suppressPackageStartupMessages(library(dplyr)))

obj <- c(12, 13, 51)
attributes(obj)<- list(cv = c(3, 4, 2))
print(obj)
#> [1] 12 13 51
#> attr(,"cv")
#> [1] 3 4 2
## 'obj' has an attribute
print(attributes(obj))
#> $cv
#> [1] 3 4 2

tbl <- tibble::tibble(col = obj)
print(tbl$col)
#> [1] 12 13 51
#> attr(,"cv")
#> [1] 3 4 2
## attributes are retained by the col obj was assigned to
print(attributes(tbl$col))
#> $cv
#> [1] 3 4 2

foo <- function(x){
  # to be called within 'summarise()'
  o <- sum(x)
  attributes(o)<- list(cvv = o*2)
  return(o)
}
# produces values with attributes
print(foo(7))
#> [1] 7
#> attr(,"cvv")
#> [1] 14

tbl2 <- tbl %>% 
  summarise(z = foo(col))
# with one single row, attributes are transferred to tbl2
print(attributes(tbl2$z))
#> $cvv
#> [1] 152

tbl2 <- tbl %>% 
  group_by(col) %>% 
  summarise(z = foo(col), .groups = "keep")
# with more rows, attributes are NO longer present in tbl2
print(attributes(tbl2$z))
#> NULL

reprex package (v0.3.0) 于 2021 年 4 月 25 日创建

【问题讨论】:

  • 您可以将它们包装在 listsummarise(z = list(foo(col)), .groups = "keep") 中,然后检查 tbl2$z 这是一个 list attributes(tbl2$z[[1]])

标签: r dplyr custom-attributes


【解决方案1】:

谢谢,是的,Akrun 你是对的,列表包装实际上保留了属性!
据我了解,要完成答案并获得所需的结果(具有属性的非列表列),需要一个相当复杂的过程(参见代码)。
是否可以在不中断“管道”流动的情况下达到相同的结果?

suppressWarnings(suppressPackageStartupMessages(library(dplyr)))
suppressWarnings(suppressPackageStartupMessages(library(purrr)))

obj <- c(12, 13, 51)
attributes(obj)<- list(cv = c(3, 4, 2))
tbl <- tibble::tibble(col = obj)
print(attributes(tbl$col))
#> $cv
#> [1] 3 4 2

foo <- function(x){
  # to be called within 'summarise()'
  o <- sum(x)
  attributes(o)<- list(cvv = o*2)
  return(o)
}

tbl2 <- tbl %>% 
  group_by(col) %>% 
  summarise(z = list(foo(col)), .groups = "keep")
atts <- map_df(tbl2$z, attributes)
tbl2 <- tbl2 %>% 
  mutate(z = unlist(z))
attributes(tbl2$z)<- atts
# now attributes are present in tbl2!!! but the flow is somewhat twisted!
print(attributes(tbl2$z))
#> $cvv
#> [1]  24  26 102

reprex package (v0.3.0) 于 2021-04-26 创建

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    相关资源
    最近更新 更多