【问题标题】:Comparison before aggregation of dataframe in RR中数据帧聚合前的比较
【发布时间】:2019-01-29 11:09:49
【问题描述】:

假设我有以下数据框,我想汇总它。为此,我需要一些额外的步骤:

  • 对于可添加的列,只需将相同的 ID 相加即可。
  • 对于不可添加的列,首先比较相同 ID 的条目,并将聚合中的值设置为较大的值。例如,对于 ID="a",我需要 Date 为 1989。
  • 对于字符,如果它们对于相同的ID相同,则使用任何条目;如果没有,则将它们与空格一起粘贴为聚合条目。

x <- data.frame(ID=c("a", "a", "b", "c", "c"), 
            Addable=c(1, 2, 3, 1, 5), 
            Date=c(1988, 1989, 2000, 2011, 2011),
            Char=c("good", "good", "fine", "yes", "no"))

如何做到这一点?尤其是比较部分和人物部分。最终,我需要的结果如下:

 ID Addable Date   Char
  a       3 1989   good
  b       3 2000   fine
  c       6 2011 yes_no

【问题讨论】:

  • 您能否为您提供的示例数据添加您的预期输出?
  • @MauritsEvers 更新了问题,关于如何处理角色部分的任何建议?

标签: r dataframe sqldf


【解决方案1】:

如果你想使用sqldf,那么下面的原始 SQL 查询应该会给你你想要的:

SELECT
    ID,
    SUM(Addable) AS addable_sum,
    MAX(Date) AS max_date,
    GROUP_CONCAT(REPLACE(DISTINCT Char, '', ''), '_') AS Char
FROM yourTable
GROUP BY ID;

这是您可以尝试的 R 代码:

library(sqldf)

sql <- "SELECT ID, SUM(Addable) AS addable_sum, MAX(Date) AS max_date,
          GROUP_CONCAT(REPLACE(DISTINCT Char, '', ''), '_') AS Char
          FROM x GROUP BY ID"

result <- sqldf(sql)

【讨论】:

  • 我认为您需要做一点小改动,以便 ID==a 的变量 Char 是“好”而不是“好_好”。
  • 一个小问题,如果列名包含“.”怎么办?例如,“ID.x”。似乎 sqldf 不接受此名称并产生错误消息 Error in result_create(conn@ptr, statement) : no such column: ID.x
  • @LaTeXFan ID.x 没有意义,也许你的意思是x.ID?您指定表名或表别名,first,后跟列名,而不是相反。
  • @milan 你什么意思?如何进行更改?
  • @TimBiegeleisen 我要说的是提供给我的数据的列名包含“。”这似乎会引起问题。我想我可以先更改列名。但是有没有办法不这样做呢?
【解决方案2】:

你可以尝试使用tidyverse

x %>% group_by(ID) %>% summarise(addable = sum(Addable), date = max(Date)) 

# A tibble: 3 x 3
  ID    addable  date
  <fct>   <dbl> <dbl>
 1 a           3  1989
 2 b           3  2000
 3 c           6  2011

【讨论】:

  • 编辑后:@tmfmnk 写出正确答案,所以我不想复制它。
【解决方案3】:

可以试试这个。 base R 解决方案使用 aggregate。对于Char 变量,我们可以使用paste0unique 的组合。

a1 <- aggregate(Addable ~ ID, x, function(x) sum(x))
a2 <- aggregate(Date ~ ID, x, function(x) max(x))
a3 <- aggregate(Char ~ ID, x, function(x) paste0(unique(x)))
merge(merge(a1, a2), a3)

  ID Addable Date    Char
1  a       3 1989    good
2  b       3 2000    fine
3  c       6 2011 yes, no

【讨论】:

  • 在我的代码中这不是问题,从输出中可以看出。 “独特”就是这样做的。
  • 有没有办法改变蒂姆的代码以获得相同的结果?
【解决方案4】:

一个dplyr 解决方案也涵盖了字符部分:

df %>%
  group_by(ID) %>%
  mutate(Char = paste0(unique(Char), collapse = "_")) %>%
  summarise(Addable = sum(Addable),
            Date = max(Date),
            Char = last(Char))

# A tibble: 3 x 4
  ID    Addable  Date Char  
  <fct>   <dbl> <dbl> <chr> 
1 a          3. 1989. good  
2 b          3. 2000. fine  
3 c          6. 2011. yes_no

【讨论】:

    【解决方案5】:

    使用by 的基础 R

    do.call(rbind, by(x, x$ID, function(.) data.frame(
             ID=.$ID[1],
             Addable = sum(.$Addable),
             Date = max(.$Date),
             Char = paste(unique(.$Char), collapse=", "),
             stringsAsFactors = FALSE)
    ))
    
    # Output
    #   ID Addable Date    Char
    # a  a       3 1989    good
    # b  b       3 2000    fine
    # c  c       6 2011 yes, no
    

    基础 R + magrittr

    # for fun only -- adding a tidyverse flavour
    x %>% 
      by(x$ID, force) %>% 
      lapply(function(.) data.frame(
        Addable = sum(.$Addable),
        Date = max(.$Date),
        Char = paste(unique(.$Char), collapse=", ")
        )) %>% 
      do.call(rbind,.)
    

    【讨论】:

      猜你喜欢
      • 2021-12-24
      • 1970-01-01
      • 2017-04-26
      • 1970-01-01
      • 2019-06-12
      • 2018-09-27
      • 2021-11-19
      • 1970-01-01
      相关资源
      最近更新 更多