簡體   English   中英

使用基數 R 和 Dplyr 使用多個函數匯總多個列

[英]Summarise multiple columns using multiple functions using base R and Dplyr

數據是這樣的:

> head(r)
  area    peri     shape perm
1 4990 2791.90 0.0903296  6.3
2 7002 3892.60 0.1486220  6.3
3 7558 3930.66 0.1833120  6.3
4 7352 3869.32 0.1170630  6.3
5 7943 3948.54 0.1224170 17.1
6 7979 4010.15 0.1670450 17.1

我想在每一列上執行多個功能,我目前擁有的是這個 function:

analysis = function(df){
  measurements = data.frame(attributes = character(),
                            mean = double(),
                            median = double(),
                            variance = double(),
                            IQR = double())
  for (i in 1:ncol(df)){
    names = colnames(df)[i]
    temp = data.frame(attribute = names,
                                   mean = mean(df[,i]),
                                   median = median(df[,i]),
                                   variance = var(df[,i]),
                                   IQR = IQR(df[,i]))
    measurements = rbind(measurements, temp)
  }
  return (measurements)
}

它運行良好並實現了我想要的,它給出了以下 output:

  attribute         mean      median     variance          IQR
1      area 7187.7291667 7487.000000 7.203045e+06 3564.2500000
2      peri 2682.2119375 2536.195000 2.049654e+06 2574.6150000
3     shape    0.2181104    0.198862 6.971657e-03    0.1004083
4      perm  415.4500000  130.500000 1.916848e+05  701.0500000

但是,我的主管說這效率不高,而且沒有以 R 的方式思考。 我還嘗試了summarise_each()summarise_all(r, funs(mean, median, var, IQR))但它沒有達到我想要的效果,而且 output 看起來不太好。

還有哪些其他方法可以僅使用基數 R 或 dplyr 來實現 output。

我懷疑您的主管評論“R”式思維是關於使用 for 循環的。 您編寫的幾乎所有for loop都可以替換為apply函數系列(例如applysapplylapply等)。

它們使在 vectors/data.frames/lists/etc 上運行函數變得更容易。

你可以使用apply函數做的所有事情都可以在 for 循環中復制(通常具有相似的性能)所以使用 for 循環實際上並不是一個大罪。 為什么要使用apply函數? 好吧......一旦你學會了它們,你就會得到更簡潔的代碼,這些代碼會返回在你的數據上運行你的函數的結果。 不久之后,您會發現這種代碼非常直觀,甚至比 for 循環更具可讀性。

基地 R

df <- data.frame(
  area = c(4990, 7002, 7558, 7352, 7943),
  peri = c(2791.9, 3892.6, 3930.66, 3869.32, 3948.54),
  shape = c(.0903296, .148622, .183312, .117063, .122417),
  perm = c(6.3, 6.3, 6.3, 6.3, 17.1)
)

sapply(df, function(x) c(mean=mean(x), median=median(x), var=var(x), IQR=IQR(x)))

您的結果可以使用base::Map實現:

f <- function(x) {
  desc = base::summary(x)
  c(
    Mean = unname(desc['Mean']),
    Median = unname(desc['Median']),
    Variance = base::sum((x-desc['Mean'])**2)/(length(x)-1),
    IQR = unname(desc['3rd Qu.'] - desc['1st Qu.'])
  )
}

t(as.data.frame(base::Map(f, df)))
#               Mean       Median     Variance          IQR
# area  7137.3333333 7455.0000000 1.241980e+06 757.25000000
# peri  3740.5283333 3911.6300000 2.183447e+05  68.93000000
# shape    0.1381314    0.1355195 1.192633e-03   0.04403775
# perm     9.9000000    6.3000000 3.110400e+01   8.10000000

道歉

數據:

df <- data.frame(
  area = c(4990, 7002, 7558, 7352, 7943, 7979),
  peri = c(2791.9, 3892.6, 3930.66, 3869.32, 3948.54, 4010.15),
  shape = c(.0903296, .148622, .183312, .117063, .122417, .167045),
  perm = c(6.3, 6.3, 6.3, 6.3, 17.1, 17.1)
)

希望這有用。

暫無
暫無

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

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