【问题标题】:Difficulty in grouping variables and apply function to groups难以对变量进行分组并将函数应用于组
【发布时间】:2016-01-09 09:09:07
【问题描述】:

我需要将我的数据分成 2 或 3 个选择级别,并对每个特定组应用一个函数。当我使用标准函数(平均值、中值、SD)时,tapply 命令会执行此操作,但是当我插入多个过滤器变量时,它就不起作用了。

代码:

  tipo      <-  rep(LETTERS[1:3], 9)
  vendedor  <-  rep(LETTERS[11:13], 9)        
  produto   <-  rep(LETTERS[17:19],9)
  valor     <-  trunc(rnorm(27,1000,50)) 
  dados     <-  data.frame(tipo, vendedor, produto, valor)
  funcao    <-  function(dados) c(media = mean(valor), 
                                 desvio = sd(valor)*0.23)
  simplify2array(tapply(dados$valor, dados$tipo, funcao))
  simplify2array(tapply(dados$valor, list(dados$tipo, dados$vendedor), funcao))

命令tapply 1的输出,运行正常:

> simplify2array(tapply(dados$valor, dados$tipo, funcao))
            A          B          C
media  998.370370 998.370370 998.370370
desvio   9.763732   9.763732   9.763732

tapply 2 命令的输出,不能正常工作:

> simplify2array(tapply(dados$valor, list(dados$tipo, dados$vendedor), funcao))
  K         L         M        
A Numeric,2 NULL      NULL     
B NULL      Numeric,2 NULL     
C NULL      NULL      Numeric,2

有谁知道我该如何解决这个问题?

【问题讨论】:

    标签: r grouping tapply


    【解决方案1】:

    据我了解,您有一个函数 funcao 返回 2 个元素(media 和 desvio),并且您希望使用 tapply 将其应用于每个 tipo/vendedor 配对。你可以这样做:

    funcao <- function(valor) c(media = mean(valor), desvio = sd(valor)*0.23)
    simplify2array(tapply(dados$valor, paste(dados$tipo, dados$vendedor), funcao))
    #              A K       B L        C M
    # media  967.11111 989.11111 1001.55556
    # desvio  12.55158  12.63768   11.27241
    

    基本上我所做的只是将分组变量从list(dados$tipo, dados$vendedor) 更改为paste(dados$tipo, dados$vendedor),这只是将tipo 和vendedor 变量粘贴在一起。感谢@thelatemail 的评论,我还更新了funcao 以使用它的论点。

    【讨论】:

    • 或interaction(tipo,vendedor,drop=TRUE) - 还应编辑函数以作用于每个组,例如function(x) c(media=mean(x), desvio=sd(x)*0.23),否则它只会为每个组提供相同的结果。
    • @thelatemail 好眼光——我没有注意到 OP 的函数没有使用传递的参数!
    • hiii,谢谢!!!伙计们的想法有效,但是当我应用另一个功能时,却没有。我的工作有错吗?我哪里错了? homo &lt;- function (a){ a &lt;- a[order(a$valor),] n &lt;- nrow(a) # sobra &lt;- rep(NA, n -1) for(i in 1:n){ a$sobra[i] = round(((a$valor[i+1] / a$valor[i])*100)-100, dig = 2) } a &lt;- subset (a, a$sobra &lt; 50) return (a) }
    • @WoldineiMeier 很难阅读 cmets 中发布的代码。如果您需要编辑此问题以提供更多详细信息,请执行此操作。如果您提出新问题,请使用“”按钮提出新问题。
    猜你喜欢
    • 2011-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-12
    • 2016-11-18
    • 1970-01-01
    • 2023-04-07
    • 2014-09-05
    相关资源
    最近更新 更多