当前位置: 首页 > 知识库问答 >
问题:

如何对函数进行泛化,以便在不更改参数的情况下传递任何数据集?

洪高阳
2023-03-14

我感兴趣的是设计一个用户构建的函数,在其中输入任何包含因子和数值的数据集,并以csv格式生成输出。

我尝试过使用各种形式的dplyr,但我认为选择提取我的变量,我仍然希望它是我的数据集的一部分,所以函数组织我的各种因素。

我想出了一个函数的两个想法。它们中的一些是有效的,但是我把所有的东西都塞进了函数中,所以我出错了。

the_function <- function(df){
  library(dplyr) #Import library
  
  #Computes Summary statistics independently
  Avg <-  df %>% 
    group_by(across(where(is.factor))) %>%
    summarise(across(where(is.numeric), mean)) #Thanks to akrun
              
  Med <- df %>% 
    group_by(across(where(is.factor))) %>%
    summarise(across(where(is.numeric)), median)
    
  StDev <- df %>% 
    group_by(across(where(is.factor))) %>%
    summarise(across(where(is.numeric)), sd)
  
  #Parse objects to new dataframe and write dataframe to CSV file
  e <-  data.frame(Avg, Med, Sample, StDev)
  return(e)
}

我在比较dplyr和基本R,为了简洁起见,代码更少

another_function <- function(df){
  for(x in df){
    if(is.numeric(x) == TRUE){
      x <- x
      break
    }
  }
  ag <- aggregate(x~., data = df, mean) #So it aggregates n groups. Running into issues sometimes with .groups
  e <- data.frame(ag)
  return(e)
}

我很好奇为什么dplyr会进化,以及如何产生更复杂的功能,以便将来在研究和咨询中使用,我对用户构建的功能很感兴趣。感谢您的智慧!

共有2个答案

乐正秦斩
2023-03-14

< code>dplyr的管道可以写成

library(dplyr)
df %>%
    group_by(across(where(is.factor))) %>%
    summarise(across(where(is.numeric), mean))

在OP的代码中,当我们调用多个< code > cross 时,列是重复的。相反,它可以在单个< code > cross 中

library(dplyr) 
the_function <- function(df){



     out <- df %>%
        group_by(across(where(is.factor))) %>%
        summarise(
          Observations = n(),

          across(where(is.numeric),  
         list(Mean = ~ mean(., na.rm = TRUE),
              Median = ~ median(., na.rm = TRUE),
              Sd.dev = ~ sd(., na.rm = TRUE))))

   return(out)
  }

-测试

the_function(iris)
# A tibble: 3 x 17
  Species    Observations Sepal.Length_Mean Sepal.Length_Median Sepal.Length_Sd.d… Sepal.Width_Mean Sepal.Width_Medi… Sepal.Width_Sd.d… Petal.Length_Me…
* <fct>             <int>             <dbl>               <dbl>              <dbl>            <dbl>             <dbl>             <dbl>            <dbl>
1 setosa               50              5.01                 5                0.352             3.43               3.4             0.379             1.46
2 versicolor           50              5.94                 5.9              0.516             2.77               2.8             0.314             4.26
3 virginica            50              6.59                 6.5              0.636             2.97               3               0.322             5.55
# … with 8 more variables: Petal.Length_Median <dbl>, Petal.Length_Sd.dev <dbl>, Petal.Width_Mean <dbl>, Petal.Width_Median <dbl>,
#   Petal.Width_Sd.dev <dbl>, Observations_Mean <dbl>, Observations_Median <int>, Observations_Sd.dev <dbl>

关于< code>base R,我们可以得到类似的摘要输出,但是没有< code>tidyverse那么灵活

the_function_base <- function(df) {
      grp <- names(df)[sapply(df, is.factor)]
      num_cols <- names(df)[sapply(df, is.numeric)]
      fmla <- reformulate(grp, response = '.')
      f1 <- function(x) {
              c(Mean = mean(x, na.rm = TRUE),
              Median = median(x, na.rm = TRUE),
              Sd.dev = sd(x, na.rm = TRUE))
          }
      do.call(data.frame, aggregate(fmla, df[c(grp, num_cols)], FUN = 
           f1))
    }
    

-测试

the_function_base(iris)
     Species Sepal.Length.Mean Sepal.Length.Median Sepal.Length.Sd.dev Sepal.Width.Mean Sepal.Width.Median Sepal.Width.Sd.dev Petal.Length.Mean
1     setosa             5.006                 5.0           0.3524897            3.428                3.4          0.3790644             1.462
2 versicolor             5.936                 5.9           0.5161711            2.770                2.8          0.3137983             4.260
3  virginica             6.588                 6.5           0.6358796            2.974                3.0          0.3224966             5.552
  Petal.Length.Median Petal.Length.Sd.dev Petal.Width.Mean Petal.Width.Median Petal.Width.Sd.dev
1                1.50           0.1736640            0.246                0.2          0.1053856
2                4.35           0.4699110            1.326                1.3          0.1977527
3                5.55           0.5518947            2.026                2.0          0.2746501
司空元凯
2023-03-14

我不得不跳到R Studio社区进行更多的讨论,但我已经找到了我的程序的解决方案。

the_function <- function(df){
  library(dplyr) #Import library
  
  #Computes Summary statistics
  out <- df %>%
    group_by(across(where(is.factor))) %>%
    summarise(
      Observations = n(),
      Mean = across(.cols = where(is.numeric),
                     .fns = ~ mean(.x, na.rm = T)),
      Median = across(.cols = where(is.numeric),
                      .fns = ~ median(.x, na.rm = T)),
      St.dev = across(.cols = where(is.numeric),
                      .fns = ~ sd(.x, na.rm = T)))
  return(out)
}

出于某种原因,它会产生重复的列和具有NA值的列,但我已经能够用单独的数据集来验证它。我假设这些额外的列来自dplyr::summary()中的怪癖,但是已经过了我的就寝时间,所以我就不写了。

在R基地完成同样的任务是徒劳的吗?谢谢你让我第一次进入数据科学的世界。

 类似资料:
  • 问题内容: 我最近开始学习Scala,但对它们的泛型也通过类型擦除实现感到失望(但并不感到惊讶)。 我的问题是,Scala是否可以使用通用化泛型,或者需要以某种方式更改JVM?如果确实需要更改JVM,则到底需要更改什么? 问题答案: 否-如果该Scala字节码不支持统一的泛型,则Scala不可能作为Java等效字节码运行。 当您问 “需要更改什么?”时 ,答案是: 字节码规范 。当前,字节码不允许

  • 我的数据如下所示 H123412341999-12-03.3.22.34.132456 G134523451998-11-03-12.22.45.23456 你能告诉我如何解决这个问题吗?

  • 我正在初始化的代码: 如何根据 类型在我的 函数中启动 ? ps-getForObject是spring restTemplate的标准函数-http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#getForObject-java.lang.Str

  • 本文向大家介绍如何在PowerShell函数中传递参数?,包括了如何在PowerShell函数中传递参数?的使用技巧和注意事项,需要的朋友参考一下 您可以在PowerShell函数中传递参数,并且要捕获这些参数,需要使用参数。通常,当您在函数外部使用变量时,您实际上不需要传递参数,因为变量本身是Public,可以在函数内部访问。但是在某些情况下,我们需要将参数传递给函数,下面的示例说明了如何编写该

  • 问题内容: 我正在尝试为我的应用程序编写查询,但是遇到了一些麻烦。我需要将数据库的一个字段作为参数传递,例如: 因为WHERE子句和ORDER BY子句是动态的,所以用户可以选择。 使用它没有用。 问题答案: JasperReports中 有两个用于参数引用的语法表达式: 和和 。 $ P {paramName}语法 主要用于设置 WHERE 输入参数值。替换算法是“智能”的,其实现使用java.

  • 本文向大家介绍在某些情况下如何更改R数据帧中的列?,包括了在某些情况下如何更改R数据帧中的列?的使用技巧和注意事项,需要的朋友参考一下 有时,特定列的列值与另一列有某种关系,我们可能需要根据某些条件来更改该特定列的值。我们需要进行此更改,以检查列值的更改如何对所考虑的两个列之间的关系产生影响。在R中,我们可以使用单个方括号来更改列值。 示例 请看以下数据帧- 假设我们想从第2列(x2)值中减去2,