首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >编写R函数,该函数仅在声明时进行子集设置

编写R函数,该函数仅在声明时进行子集设置
EN

Stack Overflow用户
提问于 2021-12-13 21:38:57
回答 2查看 47关注 0票数 0

我正在尝试编写一个函数,从特定列(深度)的数据帧中提取方法和min和max,它可以被两个分类变量分类,因此在函数中,一个是按类型变量分组的。另一个分类变量是在2020年或2021年收集的数据。我希望默认函数提取所有年份的数据,除非在参数中说明,然后按年对数据进行子集。如果我能改变变量(比如长度而不是深度),那也是很好的。这是我的密码

代码语言:javascript
运行
复制
analysis <- function(data=measurements, yearX=2020){
  data %>%
    subset(year == yearX) %>%  ## Subsets the dataset by specific year
    group_by(type) %>%  ## groups the data by type 
    summarise(mBD=mean(depth), sdBD=sd(depth), minBD=min(depth),
              maxBD=max(depth), median=median(depth), 
              range=(max(depth) - min(depth)))
}
EN

回答 2

Stack Overflow用户

发布于 2021-12-13 22:01:34

实现您期望的结果的一个选项可能如下所示:

代码语言:javascript
运行
复制
set.seed(123)

measurements <- data.frame(
  year = rep(2020:2021, each = 10),
  type = rep(c("A", "B")),
  length = runif(20),
  depth = runif(20)
)

library(dplyr)

analysis <- function(data = measurements, x, yearX = NULL) {
  # Subset by year if given
  if (!is.null(yearX)) data <- filter(data, year %in% yearX) 
  data %>%
    group_by(type) %>%
    summarise(across({{x}}, .fns = list(
      mBD = mean, 
      sdBD = sd, 
      minBD = min, 
      maxBD = max, 
      median = median, 
      range = ~ diff(range(.x))), .names = "{.fn}"
      ))
}

analysis(x = depth)
#> # A tibble: 2 × 7
#>   type    mBD  sdBD  minBD maxBD median range
#>   <chr> <dbl> <dbl>  <dbl> <dbl>  <dbl> <dbl>
#> 1 A     0.577 0.290 0.0246 0.963  0.648 0.938
#> 2 B     0.576 0.299 0.147  0.994  0.643 0.847

analysis(measurements, depth, 2020)
#> # A tibble: 2 × 7
#>   type    mBD  sdBD minBD maxBD median range
#>   <chr> <dbl> <dbl> <dbl> <dbl>  <dbl> <dbl>
#> 1 A     0.604 0.217 0.289 0.890  0.641 0.600
#> 2 B     0.627 0.307 0.147 0.994  0.693 0.847

analysis(measurements, length, 2021)
#> # A tibble: 2 × 7
#>   type    mBD  sdBD  minBD maxBD median range
#>   <chr> <dbl> <dbl>  <dbl> <dbl>  <dbl> <dbl>
#> 1 A     0.462 0.348 0.103  0.957  0.328 0.854
#> 2 B     0.584 0.370 0.0421 0.955  0.573 0.912
票数 1
EN

Stack Overflow用户

发布于 2021-12-14 06:49:22

为了从函数中使用subset()的方便性,我们可以使用match.call()matchformalArgs of subset.default一起创建一个subset调用,我们可以使用evaluate。如果没有指定子集,则行类似于省略。

对于剩下的部分,我们定义了一个汇总函数,在这里我们应该定义当有NA's时会发生什么,并在aggregate()中使用它,并使用一个很容易用reformulate()创建的公式。

有了案例处理,我们也可以省略分组。

代码语言:javascript
运行
复制
FUN <- function(..., col, group=NA, na.rm=FALSE) {
  cll <- match.call()
  m <- match(formalArgs(subset.default), names(cll), 0L)
  m <- cll[c(1L, m)]
  m[[1L]] <- quote(subset)
  dat <- eval(m)
  mysum <- function(x) c(mBD=mean(x, na.rm=na.rm), sdBD=sd(x, na.rm=na.rm), 
                         minBD=min(x, na.rm=na.rm), maxBD=max(x, na.rm=na.rm), 
                         median=median(x, na.rm=na.rm), 
                         range=max(x, na.rm=na.rm) - min(x, na.rm=na.rm))
  if (!is.na(group)) {
    res <- aggregate(reformulate(group, col), dat, mysum)
  } else {
    res <- mysum(dat[, col])
  }
  return(res)
}

用法

代码语言:javascript
运行
复制
FUN(x=measurements, col='depth', group='type')
#   type  depth.mBD depth.sdBD depth.minBD depth.maxBD depth.median depth.range
# 1    A 0.57739614 0.29037002  0.02461368  0.96302423   0.64810631  0.93841055
# 2    B 0.57604555 0.29862847  0.14711365  0.99426978   0.64347271  0.84715613

FUN(x=measurements, col='depth', group='type', subset=year == 2020)
#   type depth.mBD depth.sdBD depth.minBD depth.maxBD depth.median depth.range
# 1    A 0.6037955  0.2169419   0.2891597   0.8895393    0.6405068   0.6003796
# 2    B 0.6273719  0.3070970   0.1471136   0.9942698    0.6928034   0.8471561

FUN(x=measurements, col='length', group='type', subset=year == 2020)
#   type length.mBD length.sdBD length.minBD length.maxBD length.median length.range
# 1    A  0.5433124   0.2457008    0.2875775    0.9404673     0.5281055    0.6528898
# 2    B  0.6131826   0.3633747    0.0455565    0.8924190     0.7883051    0.8468625

FUN(x=measurements, col='depth', group=NA)
#        mBD       sdBD      minBD      maxBD     median      range 
# 0.57672085 0.28667353 0.02461368 0.99426978 0.64810631 0.96965609  

数据(从斯特凡借用):

代码语言:javascript
运行
复制
measurements <- structure(list(year = c(2020L, 2020L, 2020L, 2020L, 2020L, 2020L, 
2020L, 2020L, 2020L, 2020L, 2021L, 2021L, 2021L, 2021L, 2021L, 
2021L, 2021L, 2021L, 2021L, 2021L), type = c("A", "B", "A", "B", 
"A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", 
"B", "A", "B"), length = c(0.287577520124614, 0.788305135443807, 
0.4089769218117, 0.883017404004931, 0.940467284293845, 0.0455564993899316, 
0.528105488047004, 0.892419044394046, 0.551435014465824, 0.456614735303447, 
0.956833345349878, 0.453334156190977, 0.677570635452867, 0.572633401956409, 
0.102924682665616, 0.899824970401824, 0.24608773435466, 0.0420595335308462, 
0.327920719282702, 0.954503649147227), depth = c(0.889539316063747, 
0.6928034061566, 0.640506813768297, 0.994269776623696, 0.655705799115822, 
0.708530468167737, 0.544066024711356, 0.59414202044718, 0.28915973729454, 
0.147113647311926, 0.963024232536554, 0.902299045119435, 0.690705278422683, 
0.795467417687178, 0.0246136845089495, 0.477795971091837, 0.758459537522867, 
0.216407935833558, 0.318181007634848, 0.231625785352662)), class = "data.frame", row.names = c(NA, 
-20L))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70341256

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档