【问题标题】:How to calculate statistics for specific range with 2 Group Variables in R?如何使用 R 中的 2 个组变量计算特定范围的统计数据?
【发布时间】:2014-06-25 08:40:24
【问题描述】:

我有点问题。

我有一列数据 (P),我想分析(平均值、标准差等)并针对另一列(频率)作图。数据集示例如下所示。

Frequency Voltage P
20000     10      0.12
20000     10      0.23
20000     10      0.51
20000     20      0.45
20000     20      0.01
20000     20      0.94  
30000     10      0.66
30000     10      0.36
30000     10      0.18
30000     20      0.05
30000     20      0.15
30000     20      0.83

我遇到的问题是计算对应于频率 = 20000 和电压 = 10 的 P 范围的平均值。

那里的大多数示例只使用一个组,如下所示:

by(df$P, df$Frequency, mean)

有没有办法计算出来,让dataframe变成:

Frequency Voltage P(average)
20000     10      ...
20000     20      ...
30000     10      ...
30000     20      ...

编辑:

我设法找到了我需要的平均值和标准差:

df$mean<-ave(df$P, df$Voltage, df$Frequency, FUN=mean)
df$sd<-ave(df$P, df$Voltage, df$Frequency, FUN=sd)

但他们给了我重复的价值观。现在,有没有办法压缩所有这些,所以我只得到上面的数据框?

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    尝试使用listformula 表示法aggregate

    # your data
    df <- read.table(text="Frequency Voltage P
    20000     10      0.12
    20000     10      0.23
    20000     10      0.51
    20000     20      0.45
    20000     20      0.01
    20000     20      0.94  
    30000     10      0.66
    30000     10      0.36
    30000     10      0.18
    30000     20      0.05
    30000     20      0.15
    30000     20      0.83", header=TRUE)
    
    # list notation
    with(df, aggregate(P, list(Frequency=Frequency, Voltage=Voltage), FUN=mean))
    #  Frequency Voltage         x
    #1     20000      10 0.2866667
    #2     30000      10 0.4000000
    #3     20000      20 0.4666667
    #4     30000      20 0.3433333
    
    # formula notation
    aggregate(P ~ Frequency + Voltage, data=df, FUN=mean)
    #  Frequency Voltage         P
    #1     20000      10 0.2866667
    #2     30000      10 0.4000000
    #3     20000      20 0.4666667
    #4     30000      20 0.3433333
    

    要将多个统计信息放在一起(例如,meansd),您可以将结果 cbind 在一起:

    > cbind(aggregate(P ~ Frequency + Voltage, data=df, FUN=mean),
            sd = aggregate(P ~ Frequency + Voltage, data=df, FUN=sd)$P)
      Frequency Voltage         P        sd
    1     20000      10 0.2866667 0.2010804
    2     30000      10 0.4000000 0.2424871
    3     20000      20 0.4666667 0.4652240
    4     30000      20 0.3433333 0.4244212
    

    或者,您可以编写自己的函数来返回值向量,但是您必须做一些额外的工作来将结果存储在它们自己的列中:

    > myfun <- function(x) c(mean(x), sd(x))
    > x <- aggregate(P ~ Frequency + Voltage, data=df, FUN=myfun)
    > x[,3:4] <- x[,3]
      Frequency Voltage         P        V4
    1     20000      10 0.2866667 0.2010804
    2     30000      10 0.4000000 0.2424871
    3     20000      20 0.4666667 0.4652240
    4     30000      20 0.3433333 0.4244212
    

    【讨论】:

    • 完美!谢谢!但是有没有办法使用聚合添加其他统计值(P ~ 频率 + 电压,数据=df,FUN=mean)
    • @user3771106 您必须为每个统计信息运行aggregate,并同时运行cbind 结果。
    • 谢谢你们的帮助,伙计们!
    【解决方案2】:

    或者

    library(data.table)
    setDT(df)[, list(Mean = mean(P), SD = sd(P)), by = list(Frequency, Voltage)]
    
    ##   Frequency Voltage      Mean        SD
    ##1:     20000      10 0.2866667 0.2010804
    ##2:     20000      20 0.4666667 0.4652240
    ##3:     30000      10 0.4000000 0.2424871
    ##4:     30000      20 0.3433333 0.4244212
    

    【讨论】:

    • 谢谢。虽然我似乎无法下载 data.table 包。我正在使用 RStudio。
    • install.packages("data.table")
    【解决方案3】:

    library(dplyr)
    df%>% #?%>% chain multiple operations
    group_by(Frequency,Voltage)%>% #group by variables `Frequency`, `voltage`
    summarise(Mean=mean(P), SD=sd(P)) ##get the `mean` and `sd` of column `P` 
    

    【讨论】:

    • 虽然这个代码块可能会回答这个问题,但最好能稍微解释一下为什么会这样。
    • @akrun,别介意他。他甚至不认识R。他来这里是因为某个白痴将您的答案标记为低质量,而您的答案并不比其他任何人都差
    【解决方案4】:

    对于获取值的简单解决方案,请使用 tapply:

    with(df, tapply(P, list(Frequency, Voltage), mean))
                 10        20
    20000 0.2866667 0.4666667
    30000 0.4000000 0.3433333
    
    with(df, tapply(P, list(Frequency, Voltage), sd))
                 10        20
    20000 0.2010804 0.4652240
    30000 0.2424871 0.4244212
    

    For loop & cat 命令可用于根据需要进行格式化输出:

    for(x in unique(df$Voltage)) 
        for(y in unique(df$Frequency))  {
            cat("Voltage=",x,"; Frequency=",y,"; Mean P=");
            cat(mean(df[df$Voltage==x & df$Frequency==y,]$P))
            cat("; SD=",sd(df[df$Voltage==x & df$Frequency==y,]$P),"\n")
        }
    
    Voltage= 10 ; Frequency= 20000 ; Mean P=0.2866667; SD= 0.2010804 
    Voltage= 10 ; Frequency= 30000 ; Mean P=0.4; SD= 0.2424871 
    Voltage= 20 ; Frequency= 20000 ; Mean P=0.4666667; SD= 0.465224 
    Voltage= 20 ; Frequency= 30000 ; Mean P=0.3433333; SD= 0.4244212 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-29
      • 1970-01-01
      相关资源
      最近更新 更多