【问题标题】:Aggregate values by levels of another factor but keep all rows in R按另一个因素的级别聚合值,但保留 R 中的所有行
【发布时间】:2017-08-14 07:31:10
【问题描述】:

我在 R 中有一个具有这种结构的数据框:

df1<-data.frame(SiteID=c("A","A","A","B","B","C"),Unrelated=c("dog","cat","catamount","bird","horse","monkey"),AirMonitor=c(1,0,0,0,0,1),WaterMonitor=c(0,1,0,1,0,0),SoilMonitor=c(0,0,1,0,1,0))

输出如下:

  SiteID Unrelated AirMonitor WaterMonitor SoilMonitor
1      A       dog          1            0           0
2      A       cat          0            1           0
3      A catamount          0            0           1
4      B      bird          0            1           0
5      B     horse          0            0           1
6      C    monkey          1            0           0

1 表示该站点存在该类型的监视器(如果需要,我可以将监视器列更改为具有 "Y""N" 值的因子)。基本上,我想通过SiteID 聚合监视器的存在,然后保留所有行,以免丢失Unrelated 列中的数据。我希望1 的价值观战胜0 的价值观。例如,如果任何带有SiteID A 的行有一个1 对应AirMonitor,我希望所有带有SiteID A 的行都有一个1 对应AirMonitor。其他两种监视器类型相同。

期望的输出:

  SiteID Unrelated AirMonitor WaterMonitor SoilMonitor
1      A       dog          1            1           1
2      A       cat          1            1           1
3      A catamount          1            1           1
4      B      bird          0            1           1
5      B     horse          0            1           1
6      C    monkey          1            0           0

真正的数据集还有几个不相关的列和数千行。必须有一些简单的方法来做到这一点(可能是aggregate?)。

【问题讨论】:

    标签: r


    【解决方案1】:

    通常,如果您想aggregate 并保持行不变,ave 可以提供帮助。因此,我们使用lapply 循环遍历列(前两列除外)并使用ave 计算SiteID 的最大值

    df1[,-c(1:2)] = lapply(df1[,-c(1:2)], function(a) ave(a, df1$SiteID, FUN = max))
    df1
    #  SiteID Unrelated AirMonitor WaterMonitor SoilMonitor
    #1      A       dog          1            1           1
    #2      A       cat          1            1           1
    #3      A catamount          1            1           1
    #4      B      bird          0            1           1
    #5      B     horse          0            1           1
    #6      C    monkey          1            0           0
    

    【讨论】:

    • 谢谢!我用c("AirMonitor","WaterMonitor","SoilMonitor") 替换了-c(1:2),因为我有很多不相关的列要保留,而且它仍然有效。
    • 我可能会使用lapply 只是为了避免sapply 所做的简化到矩阵的过程。
    【解决方案2】:

    使用dplyr

    df1 %>% group_by(SiteID) %>% mutate_at(vars(-Unrelated), funs(max)) 
    Source: local data frame [6 x 5]
    Groups: SiteID [3]
    
      SiteID Unrelated AirMonitor WaterMonitor SoilMonitor
      <fctr>    <fctr>      <dbl>        <dbl>       <dbl>
    1      A       dog          1            1           1
    2      A       cat          1            1           1
    3      A catamount          1            1           1
    4      B      bird          0            1           1
    5      B     horse          0            1           1
    6      C    monkey          1            0           0
    

    或者,如果您有多个变量,例如 Unrelated,并且不想一直指定它们,您可以考虑类似

    df %>% group_by(SiteID) %>% mutate_if(is.numeric, funs(max))
    

    这会将max 应用于每个组的每个数字列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-13
      • 1970-01-01
      • 2017-07-27
      • 1970-01-01
      • 2015-04-26
      • 1970-01-01
      • 1970-01-01
      • 2014-12-25
      相关资源
      最近更新 更多