Поскольку 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>