gpt4 book ai didi

r - tidyr::complete 带有可变长度的列名向量

转载 作者:行者123 更新时间:2023-12-04 10:29:06 25 4
gpt4 key购买 nike

我可以使用 tidyr::complete 来暴露缺失的行。

例如,使用下面的 data.frame,我可以很容易地暴露丢失的第三个季度:

suppressPackageStartupMessages({
library(dplyr)
library(tidyr)
})

set.seed(42)

df <- data.frame(
id = c(rep(1, 3), rep(2, 3)),
year = rep(2020, 3),
quarter = c(1, 2, 4),
data = runif(3)
)

df %>% complete(nesting(id, year), quarter = 1:4)
#> # A tibble: 8 x 4
#> id year quarter data
#> <dbl> <dbl> <dbl> <dbl>
#> 1 1 2020 1 0.915
#> 2 1 2020 2 0.937
#> 3 1 2020 3 NA
#> 4 1 2020 4 0.286
#> 5 2 2020 1 0.915
#> 6 2 2020 2 0.937
#> 7 2 2020 3 NA
#> 8 2 2020 4 0.286

reprex package 创建于 2020-03-02 (v0.3.0)

现在,我想为这个特定的用例创建一个包装器:它接收一个至少包含这四列的 data.frame 并公开缺失的四分之一。

这很简单,只需将 complete 调用包装在一个函数中即可:

expose <- function(df) {
complete(df, nesting(id, year), quarter = 1:4)
}

expose(df)
#> # A tibble: 8 x 4
#> id year quarter data
#> <dbl> <dbl> <dbl> <dbl>
#> 1 1 2020 1 0.915
#> 2 1 2020 2 0.937
#> 3 1 2020 3 NA
#> 4 1 2020 4 0.286
#> 5 2 2020 1 0.915
#> 6 2 2020 2 0.937
#> 7 2 2020 3 NA
#> 8 2 2020 4 0.286

但是,传入的 data.frame 可能有其他列,这些列已知对于给定的 id 是常量。在这种情况下,该函数不起作用,因为它自然地将缺失行上的那些列设置为 NA

df <- data.frame(
id = c(rep(1, 3), rep(2, 3)),
name = c(rep("A", 3), rep("B", 3)),
country = c(rep("AU", 3), rep("BR", 3)),
year = rep(2020, 3),
quarter = c(1, 2, 4),
data = runif(3)
)

expose(df)
#> # A tibble: 8 x 6
#> id year quarter name country data
#> <dbl> <dbl> <dbl> <fct> <fct> <dbl>
#> 1 1 2020 1 A AU 0.830
#> 2 1 2020 2 A AU 0.642
#> 3 1 2020 3 <NA> <NA> NA
#> 4 1 2020 4 A AU 0.519
#> 5 2 2020 1 B BR 0.830
#> 6 2 2020 2 B BR 0.642
#> 7 2 2020 3 <NA> <NA> NA
#> 8 2 2020 4 B BR 0.519

为避免这种情况,我需要将这些列添加到 nesting 调用中。

如果它只有一列,我可以为列名的函数添加一个参数,然后我将使用 nesting(..., .data[[colname]])。但是,.data 代词不适用于向量(.data[c("name1", "name2")] 不起作用)。

那么,如何向嵌套 调用添加多个变量列?

最佳答案

如果你看一下 tidyr::nesting,你会发现它依赖于 tidyr:::dots_cols,它依赖于 rlang 来解释列名称(特别是 rlang::enquos)。

因此,与 tidyr::nesting 交互的最佳方式是使用 rlang 结构。

library(dplyr)
library(tidyr)

expose <- function(df, ...) {
dots <- rlang::exprs(id, year, ...)
complete(df, nesting(!!! dots), quarter = 1:4)
}

df <- data.frame(
id = c(rep(1, 3), rep(2, 3)),
name = c(rep("A", 3), rep("B", 3)),
country = c(rep("AU", 3), rep("BR", 3)),
year = rep(2020, 3),
quarter = c(1, 2, 4),
data = runif(3)
)

expose(df)
#> # A tibble: 8 x 6
#> id year quarter name country data
#> <dbl> <dbl> <dbl> <fct> <fct> <dbl>
#> 1 1 2020 1 A AU 0.0417
#> 2 1 2020 2 A AU 0.365
#> 3 1 2020 3 <NA> <NA> NA
#> 4 1 2020 4 A AU 0.690
#> 5 2 2020 1 B BR 0.0417
#> 6 2 2020 2 B BR 0.365
#> 7 2 2020 3 <NA> <NA> NA
#> 8 2 2020 4 B BR 0.690
expose(df, name)
#> # A tibble: 8 x 6
#> id year name quarter country data
#> <dbl> <dbl> <fct> <dbl> <fct> <dbl>
#> 1 1 2020 A 1 AU 0.0417
#> 2 1 2020 A 2 AU 0.365
#> 3 1 2020 A 3 <NA> NA
#> 4 1 2020 A 4 AU 0.690
#> 5 2 2020 B 1 BR 0.0417
#> 6 2 2020 B 2 BR 0.365
#> 7 2 2020 B 3 <NA> NA
#> 8 2 2020 B 4 BR 0.690
expose(df, name, country)
#> # A tibble: 8 x 6
#> id year name country quarter data
#> <dbl> <dbl> <fct> <fct> <dbl> <dbl>
#> 1 1 2020 A AU 1 0.0417
#> 2 1 2020 A AU 2 0.365
#> 3 1 2020 A AU 3 NA
#> 4 1 2020 A AU 4 0.690
#> 5 2 2020 B BR 1 0.0417
#> 6 2 2020 B BR 2 0.365
#> 7 2 2020 B BR 3 NA
#> 8 2 2020 B BR 4 0.690

reprex package 创建于 2020-03-02 (v0.3.0)

关于r - tidyr::complete 带有可变长度的列名向量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60492646/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com