【问题标题】:Display in data.frame a conditional row count by group在 data.frame 中按组显示条件行数
【发布时间】:2016-07-29 14:36:52
【问题描述】:

我正在努力在我的 data.frame 中创建一个新变量。对于可能不太清楚的问题标题,我深表歉意。我有一个如下所示的数据库:

obs    year    type
 1     2015     A
 2     2015     A
 3     2015     B
 4     2014     A
 5     2014     B

我想在当前的 data.frame 中添加一列 (freq2015),该列按类型提供 2015 年的行数,并报告结果,不管考虑的年份,只要类型相同。这是我正在寻找的输出:

obs    year    type    freq2015
 1     2015     A         2      (there are 2 obs. of type A in 2015)
 2     2015     A         2      (there are 2 obs. of type A in 2015)
 3     2015     B         1      (there is 1 obs. of type B in 2015)
 4     2014     A         2      (there are 2 obs. of type A in 2015)
 5     2014     B         1      (there are 1 obs. of type B in 2015)

我知道如何使用dplyr 按年份向我的data.frame 添加行数:

data <- data %>% 
     group_by(year, type) %>% 
     mutate(freq = n()) 

但是,对于 year=="2014",添加的列将按种族显示 2014 行的计数,而不是 2015 年的计数。

我知道如何将 2015 年按种族划分的行数隔离到一个新的 data.frame 中:

data2015 <- dat[dat$year==2015,] %>% 
         group_by(type) %>% 
         mutate(freq2015 = n())

但我不知道如何为整个 data.frame 添加一列(2015 年的行数),条件是类型相同(如示例所示)。我正在寻找一种解决方案,可以阻止我明确使用“类型”变量模式。也就是说,我不想使用代码告诉 R:如果 type==A 则执行此操作,否则执行此操作。这个限制的原因是我的类型太多了。

有什么想法吗?提前谢谢你。

【问题讨论】:

  • 为什么要这样做?生成年份和类型计数的汇总数据框可能更容易。

标签: r dplyr


【解决方案1】:

如果您group_by 仅使用type,则可以对year == 2015 时的行求和。

data %>%
    group_by(type) %>%
    mutate(freq2015 = sum(year == 2015))

Source: local data frame [5 x 4]
Groups: type [2]

    obs  year   type freq2015
  <int> <int> <fctr>    <int>
1     1  2015      A        2
2     2  2015      A        2
3     3  2015      B        1
4     4  2014      A        2
5     5  2014      B        1

【讨论】:

  • 这是最快的方法。当要汇总的变量是一个因子而不是整数时,它也可以工作,这是个好消息:)
【解决方案2】:

使用我们可以做的数据表:

setDT(df)
setkey(df,type)
df[ df[ year==2015, .(freq2015=.N), by = type]]

结果:

     obs year type freq2015
1:   1 2015    A        2
2:   2 2015    A        2
3:   4 2014    A        2
4:   3 2015    B        1
5:   5 2014    B        1

【讨论】:

    【解决方案3】:

    您可以使用left_join(),如下所示:

    temp <- data %>% 
        filter(year==2015) %>%
        group_by(type) %>% 
        summarize(freq = n())#  %>%
    data <- data %>% left_join(temp, "type")
    

    【讨论】:

      【解决方案4】:

      我们可以通过ave 使用base R 来做到这一点(没有任何外部包),而且速度也相当快。

      df1$freq2015 <- with(df1, ave(year == 2015, type, FUN = sum))
      df1$freq2015
      #[1] 2 2 1 2 1
      

      【讨论】:

      • 确实,它工作得很好。然而,使用专用于计算计数平均值的命令并不那么直观(至少对我来说,谁是 R 新手)。你会如何用一句话解释这段代码? (我问是因为我可以看到它有效,但我真的不明白我在做什么)
      • @Elixterra dedicated to calculate average 是什么意思? ave 是一个通用函数,但默认情况下它会给出平均值,尽管您可以使用任何其他函数指定 FUN,就像这里我使用 sum 来求和按“类型”分组的逻辑索引 (year == 2015)。
      • 我不知道。我认为ave 仅用于计算平均值。我不知道这是一个通用函数,其默认操作是计算平均值,但可以重新定义。你证明我错了。感谢你的回复。我现在明白代码在做什么了:)
      猜你喜欢
      • 1970-01-01
      • 2016-11-25
      • 2022-01-10
      相关资源
      最近更新 更多