在unnest
上运行data.frame
时,有一种方法可以将嵌套项的组名添加到它包含的各个列中(后缀或前缀)。还是必须通过rename
手动进行重命名?
这与“取消嵌套”多个包含相同名称列的组特别相关。
在下面的示例中,base
aggregate
命令可以很好地完成此操作(例如Petal.Length.mn),但是我找不到让unnest
进行操作的选项。一样?
我将nest
与purrr::map
一起使用,因为我想灵活地混合使用功能,例如计算几个变量的均值和标准差,然后进行t检验以查看它们之间的差异。
library(dplyr, warn.conflicts = FALSE)
msd_c <- function(x) c(mn = mean(x), sd = sd(x))
msd_df <- function(x) bind_rows(c(mn = mean(x), sd = sd(x)))
aggregate(cbind(Petal.Length, Petal.Width) ~ Species,
data = iris, FUN = msd_c)
#> Species Petal.Length.mn Petal.Length.sd Petal.Width.mn Petal.Width.sd
#> 1 setosa 1.4620000 0.1736640 0.2460000 0.1053856
#> 2 versicolor 4.2600000 0.4699110 1.3260000 0.1977527
#> 3 virginica 5.5520000 0.5518947 2.0260000 0.2746501
iris %>%
select(Petal.Length:Species) %>%
group_by(Species) %>%
tidyr::nest() %>%
mutate(
Petal.Length = purrr::map(data, ~ msd_df(.$Petal.Length)),
Petal.Width = purrr::map(data, ~ msd_df(.$Petal.Width)),
Correlation = purrr::map(data, ~ broom::tidy(cor.test(.$Petal.Length, .$Petal.Width))),
) %>%
select(-data) %>%
tidyr::unnest(c(Petal.Length, Petal.Width, Correlation), names_repair = tidyr::tidyr_legacy)
#> # A tibble: 3 x 13
#> # Groups: Species [3]
#> Species mn sd mn1 sd1 estimate statistic p.value parameter conf.low
#> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <int> <dbl>
#> 1 setosa 1.46 0.174 0.246 0.105 0.332 2.44 1.86e- 2 48 0.0587
#> 2 versic~ 4.26 0.470 1.33 0.198 0.787 8.83 1.27e-11 48 0.651
#> 3 virgin~ 5.55 0.552 2.03 0.275 0.322 2.36 2.25e- 2 48 0.0481
#> # ... with 3 more variables: conf.high <dbl>, method <chr>, alternative <chr>
由reprex package(v0.3.0)于2020-05-20创建
答案 0 :(得分:2)
使用names_sep
选项而不是names_repair
选项,答案很明显。如nest
下的names_sep
帮助菜单中所述:
如果是字符串,则内部名称和外部名称将一起使用。在 nest(),新的外部列的名称将通过粘贴形成 外部和内部列名称一起,由names_sep分隔。 在unnest()中,新的内部名称将具有外部名称(+ names_sep)会自动删除。这使得names_sep大致 嵌套和非嵌套之间是对称的。
library(dplyr, warn.conflicts = FALSE)
msd_c <- function(x) c(mn = mean(x), sd = sd(x))
msd_df <- function(x) bind_rows(c(mn = mean(x), sd = sd(x)))
iris %>%
select(Petal.Length:Species) %>%
group_by(Species) %>%
tidyr::nest() %>%
mutate(
Petal.Length = purrr::map(data, ~ msd_df(.$Petal.Length)),
Petal.Width = purrr::map(data, ~ msd_df(.$Petal.Width)),
Correlation = purrr::map(data, ~ broom::tidy(cor.test(.$Petal.Length, .$Petal.Width))),
) %>%
select(-data) %>%
tidyr::unnest(c(Petal.Length, Petal.Width, Correlation), names_sep = ".")
#> # A tibble: 3 x 13
#> # Groups: Species [3]
#> Species Petal.Length.mn Petal.Length.sd Petal.Width.mn Petal.Width.sd
#> <fct> <dbl> <dbl> <dbl> <dbl>
#> 1 setosa 1.46 0.174 0.246 0.105
#> 2 versic~ 4.26 0.470 1.33 0.198
#> 3 virgin~ 5.55 0.552 2.03 0.275
#> # ... with 8 more variables: Correlation.estimate <dbl>,
#> # Correlation.statistic <dbl>, Correlation.p.value <dbl>,
#> # Correlation.parameter <int>, Correlation.conf.low <dbl>,
#> # Correlation.conf.high <dbl>, Correlation.method <chr>,
#> # Correlation.alternative <chr>
由reprex package(v0.3.0)于2020-06-10创建
答案 1 :(得分:0)
要将多个功能应用于多个列,我将使用summarise_at
/ mutate_at
而不是嵌套和取消嵌套数据。
例如,在这种情况下,我们可以做:
library(dplyr)
iris %>%
group_by(Species) %>%
summarise_at(vars(Petal.Length:Petal.Width), list(mn = mean, sd = sd))
# Species Petal.Length_mn Petal.Width_mn Petal.Length_sd Petal.Width_sd
# <fct> <dbl> <dbl> <dbl> <dbl>
#1 setosa 1.46 0.246 0.174 0.105
#2 versicolor 4.26 1.33 0.470 0.198
#3 virginica 5.55 2.03 0.552 0.275
这会自动在我们要应用该功能的列名称上添加前缀。此外,这是您尝试的dplyr
函数的等效aggregate
版本。
还请注意,在即将发布的summarise_at
版本中,across
很快将被dplyr
取代。
答案 2 :(得分:0)
您可以如下使用setNames
。有点罗word,但似乎您打算为每一列指定每个函数,这可能很有趣。
iris %>%
select(Petal.Length:Species) %>%
group_by(Species) %>%
tidyr::nest() %>%
mutate(
Petal.Length = purrr::map(data, ~ msd_df(.x$Petal.Length) %>%
setNames(paste0("Petal.Length.", names(.)))),
Petal.Width = purrr::map(data, ~ msd_df(.$Petal.Width) %>%
setNames(paste0("Petal.Width.", names(.)))),
Ratio = purrr::map(data, ~ msd_df(.$Petal.Length/.$Petal.Width) %>%
setNames(paste0("Ratio.", names(.))))
) %>%
select(-data) %>%
tidyr::unnest(c(Petal.Length, Petal.Width, Ratio))
# A tibble: 3 x 7
# Groups: Species [3]
Species Petal.Length.mn Petal.Length.sd Petal.Width.mn Petal.Width.sd Ratio.mn Ratio.sd
<fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 setosa 1.46 0.174 0.246 0.105 6.91 2.85
2 versicolor 4.26 0.470 1.33 0.198 3.24 0.312
3 virginica 5.55 0.552 2.03 0.275 2.78 0.407
或修改您的函数以使其能够像这样修改列名。
msd_df_name <- function(x, name){
bind_rows(c(mn = mean(x), sd = sd(x))) %>%
setNames(paste0(name, ".", names(.)))
}
iris %>%
select(Petal.Length:Species) %>%
group_by(Species) %>%
tidyr::nest() %>%
mutate(
Petal.Length = purrr::map(data, ~ msd_df_name(.x$Petal.Length, "Petal.Length")),
Petal.Width = purrr::map(data, ~ msd_df_name(.$Petal.Width, "Petal.Width")),
Ratio = purrr::map(data, ~ msd_df_name(.$Petal.Length/.$Petal.Width, "Ratio"))
) %>%
select(-data) %>%
tidyr::unnest(c(Petal.Length, Petal.Width, Ratio))