繁体   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