Получать доступ к групповым данным и избегать глубокого копирования в mutate после dplyr :: group_by - PullRequest
0 голосов
/ 19 апреля 2020

Поскольку dplyr не отправляет .data, отфильтрованный по текущей группе, в функцию mutate, я хотел бы применить функцию к подмножеству grouped_df, используя mutate. Я хотел бы получить данные для указанной c группы, но без глубокого копирования и без использования введите описание ссылки здесь group_modify, как предложено здесь . Я имею в виду, что это может быть невозможно.

Проблема

library(dplyr)

iris %>%
  group_by(Species) %>%
  mutate(
    xxx = paste(dim(.), collapse = "-")
  )

Желаемое решение

Это решение должно используйте . и создайте новый data.frame, который имеет столбцы с той же ссылкой, что и в dplyr::mutate.
Если вы посмотрите на этот пример ниже, вы заметите, что я пытался получить столбцы из .top_env подвергается мутации, и это решение возвращает правильные результаты. Проблема в том, что data.frame, который я создал, не относится к тем же блокам памяти.
Я специально оставил несколько print/cat, чтобы показать вам ссылки на объекты.

some_fun <- function(x) {
  # for debugging
  cat("------------------------\n")
  cat("ref of dplyr df\n")
  print(lobstr::ref(parent.frame(n = 1)$.top_env))

  cat("\nref of dplyr $Petal.Length\n")
  print(lobstr::ref(get("Petal.Length", parent.frame(n = 1)$.top_env)))
  cat("\n\n")


  # actual function
  new_env <- new.env(parent = parent.frame(n = 1)$.top_env)
  df_call <- as.call(
    append(
      as.name("data.frame"),
      lapply(names(x), as.name)
    )
  )

  x <- eval(df_call, envir = new_env)


  return(paste(dim(x), collapse = "-"))
}


iris %>%
  group_by(Species) %>%
  mutate(
    xxx = some_fun(.)
  )


# # A tibble: 150 x 6
# # Groups:   Species [3]
#       Sepal.Length Sepal.Width Petal.Length Petal.Width Species xxx  
#             <dbl>       <dbl>        <dbl>       <dbl> <fct>   <chr>
#   1          5.1         3.5          1.4         0.2 setosa  50-5 
#   2          4.9         3            1.4         0.2 setosa  50-5 
#   3          4.7         3.2          1.3         0.2 setosa  50-5 
#   4          4.6         3.1          1.5         0.2 setosa  50-5 
#   5          5           3.6          1.4         0.2 setosa  50-5 
#   6          5.4         3.9          1.7         0.4 setosa  50-5 
#   7          4.6         3.4          1.4         0.3 setosa  50-5 
#   8          5           3.4          1.5         0.2 setosa  50-5 
#   9          4.4         2.9          1.4         0.2 setosa  50-5 
#  10          4.9         3.1          1.5         0.1 setosa  50-5

Ссылки на объекты из первой групповой операции

# ref of dplyr df
# █ [1:0x7faf338d42e0] <env> 
#   ├─Sepal.Length = [2:0x7faf338d4ba0] <fn> 
#   ├─Petal.Length = [3:0x7faf338d5498] <fn> 
#   ├─Sepal.Width = [4:0x7faf338d5000] <fn> 
#   ├─Petal.Width = [5:0x7faf338d5930] <fn> 
#   └─Species = [6:0x7faf338d5d90] <fn> 
#   
#   ref of dplyr $Petal.Length
# [1:0x7faf39d23550] <dbl> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...