簡體   English   中英

在 R 中對自定義函數使用 sapply

[英]use sapply on custom functions in R

(使用 mtcars 和 iris 進行重現)

我創建了一個 R function get_col_info來查找數據摘要,如下所示:

  1. 如果列是numeric/integer/double精度,則獲取最小值、最大值、平均值

  2. 如果列是character/factor ,則獲取唯一值和唯一值的計數

     get_col_info <- function(data,col_name) { c_name <- c(col_name) s <- data[,c_name] type <- typeof(s) if(type %in% c("numeric","double","integer")){ min <- min(s) max <- max(s) mean <- mean(s) aa <- list(min=min, max=max,mean=mean) return(aa) } if(type %in% c("character","factor")){ uni <- unique(s) len <- length(uni) aa <- list(n_values=len,unique_values=c(uni)) return(aa)} } get_col_info(mtcars, "mpg") get_col_info(iris, "Petal.Width") get_col_info(iris, "Species")

前兩個運行完美,第三個給出錯誤,不知道為什么?

但是,現在主要的查詢是我想一次為所有列名運行這個 function,類似於sapply(iris,mean)但我不確定該怎么做,因為 function 接受 dataframe 和列名。 我試過這樣做,但它給了我一個錯誤

sapply(iris,get_col_info(iris,names(iris)))

Error in match.fun(FUN) : 
  'get_col_info(iris, names(iris))' is not a function, character or symbol

歡迎使用 apply 和 purrr 解決方案。 我也在找人告訴我如何才能更好地編寫我的 function,我懷疑我創建的 c_name 不是捕獲列名的理想方式。

您應該使用class檢查類型而不是typeof

get_col_info <- function(data,col_name) {    
  s <- data[,col_name]
  type <- class(s)
  if(type %in% c("numeric","double","integer")){
    min <- min(s)
    max <- max(s)
    mean <- mean(s)
    aa <- list(min=min, max=max,mean=mean)
    return(aa)
  }
  else if(type %in% c("character","factor")){
    uni <- as.character(unique(s))
    len <- length(uni)
    aa <- list(n_values=len,unique_values=uni)
    return(aa)
  }
}

查看output:

get_col_info(mtcars, "mpg")
#$min
#[1] 10.4

#$max
#[1] 33.9

#$mean
#[1] 20.09062

get_col_info(iris, "Species")
#$n_values
#[1] 3

#$unique_values
#[1] "setosa"     "versicolor" "virginica" 

要為多個列運行此操作,您可以使用:

sapply(names(iris), get_col_info, data = iris)

或者如果您對purrr解決方案感興趣,請將sapply替換為map


另一種方法是直接傳遞列值而不是名稱。

get_col_info <- function(s) {    
  if(is.numeric(s)) {
    min <- min(s)
    max <- max(s)
    mean <- mean(s)
    aa <- list(min=min, max=max,mean=mean)
    return(aa)
  }
  else {
    uni <- as.character(unique(s))
    len <- length(uni)
    aa <- list(n_values=len,unique_values=uni)
    return(aa)
  }
}

sapply(iris, get_col_info)

您可以使用summariseacross進行此操作,並進行類型檢查(如is.numeric ):

library(dplyr)

iris %>%
  summarise(across(where(is.numeric), list(min=min, max=max, mean=mean)),
            across(where(~is.factor(.) | is.character(.)), 
                   list(n_values = ~length(unique(.)), 
                        unique_values = ~as.character(unique(.))))) %>%
  glimpse()

Output:

Rows: 3
Columns: 14
$ Sepal.Length_min      <dbl> 4.3, 4.3, 4.3
$ Sepal.Length_max      <dbl> 7.9, 7.9, 7.9
$ Sepal.Length_mean     <dbl> 5.843333, 5.843333, 5.843333
$ Sepal.Width_min       <dbl> 2, 2, 2
$ Sepal.Width_max       <dbl> 4.4, 4.4, 4.4
$ Sepal.Width_mean      <dbl> 3.057333, 3.057333, 3.057333
$ Petal.Length_min      <dbl> 1, 1, 1
$ Petal.Length_max      <dbl> 6.9, 6.9, 6.9
$ Petal.Length_mean     <dbl> 3.758, 3.758, 3.758
$ Petal.Width_min       <dbl> 0.1, 0.1, 0.1
$ Petal.Width_max       <dbl> 2.5, 2.5, 2.5
$ Petal.Width_mean      <dbl> 1.199333, 1.199333, 1.199333
$ Species_n_values      <int> 3, 3, 3
$ Species_unique_values <chr> "setosa", "versicolor", "virginica"

注意:我添加了glimpse()以使 output 更具可讀性,這不是必需的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM