【问题标题】:Merge Rows by ID and Date按 ID 和日期合并行
【发布时间】:2018-07-21 22:55:29
【问题描述】:

我是 R 的新手,我一直在寻找如何解决以下问题。

我有一个看起来像这样的 df:

id------------日期 ------------OB1------ OB2----- OB3
1 ----- 2017-01-01 --------- 1 --------- 0--------- 0
2 ----- 2006-01-05 --------- 1 --------- 0--------- 0
2 ----- 2007-04-19 --------- 0 --------- 1--------- 0
3 -------- 2015-02-23 --------- 0 --------- 0--------- 1
3 ----- 2015-02-23 --------- 1 --------- 0--------- 0

这里显示了我必须实现的目标:

id------------日期 ------------OB1------ OB2----- OB3
1 ----- 2017-01-01 --------- 1 --------- 0--------- 0
2 ----- 2006-01-05 --------- 1 --------- 0--------- 0
2 ----- 2007-04-19 --------- 0 --------- 1--------- 0
3 ------- 2015-02-23 --------- 1 --------- 0--- ------ 1

这是按 id 和日期组合行。

如果 OB3 在同一日期的值为“1”,而 OB1 的值为“1”,则在同一日期(对于相同的 ID),结果必须为 OB1 的值“1”,“OB3”的值为“1” ' 和一个日期

我一直在尝试应用这里解释的一些解决方案: Merge rows having same values in multiple columns

但是没用

编辑:OB1、OB2、OBS3 是布尔值 感谢您的帮助!

编辑 2:聚合(。~ ID + Date, df, any) 有效!


样本数据

输入数据

structure(list(ID = c(-1L, 1L, 1L), Date = c("2008-01-15", "2011-01-21", "2011-01-21"), `OBS1` = c(0, 0, 0), `OBS2` = c(0, 0, 0), `OBS3` = c(0, 0, 0), `OBS4` = c(0, 0, 0), `OBS5` = c(0, 0, 0), `OBS6` = c(0, 1, 0)), .Names = c("ID", "Date", "OBS1", "OBS2", "OBS3", "OBS4", "OBS5", "OBS6"), row.names = c(NA, 3L), class = "data.frame")

输出数据

structure(list(ID = c(-1L, 1L), Date = c("2008-01-15", "2011-01-21"), `OBS1` = c(FALSE, FALSE), `OBS2` = c(FALSE, FALSE), `OBS3` = c(FALSE, FALSE), `OBS4` = c(FALSE, FALSE), `OBS5` = c(FALSE, FALSE), `OBS6` = c(FALSE, TRUE)), .Names = c("ID", "Date", "OBS1", "OBS2", "OBS3", "OBS4", "OBS5", "OBS6"), row.names = c(NA, -2L), class = "data.frame")

【问题讨论】:

  • 请在您的问题中包含究竟是什么不起作用!
  • aggregate(. ~ id + Date, df, sum)
  • @alistaire 用那句话,我得到了 OB1 值 '2' 和 OB2 值 '0'。
  • 也许只是aggregate(. ~ Date, df[, -1], sum)
  • any替换sum?

标签: r date merge


【解决方案1】:

已经使用 base R 的 aggregate() 函数回答了这个问题。

但是,将问题中打印的示例数据集转换为可重现的示例(OP 编辑​​问题以包含dput() 的结果之前),我感到面临挑战。

此外,OP 提到他有一个 “非常大的 df”,这可能值得尝试 data.table 方法。

将示例数据转换为数据框

library(magrittr)
library(data.table)
df <- readr::read_file(
"id------------Date ------------OB1------ OB2----- OB3
1 ------- 2017-01-01 --------- 1 --------- 0--------- 0
2 ------- 2006-01-05 --------- 1 --------- 0--------- 0
2 ------- 2007-04-19 --------- 0 --------- 1--------- 0
3 ------- 2015-02-23 --------- 0 --------- 0--------- 1
3 ------- 2015-02-23 --------- 1 --------- 0--------- 0"
) %>% stringr::str_replace_all("[-]{2,}", " ") %>% 
  fread()
df
   id       Date   OB1   OB2   OB3
1:  1 2017-01-01  TRUE FALSE FALSE
2:  2 2006-01-05  TRUE FALSE FALSE
3:  2 2007-04-19 FALSE  TRUE FALSE
4:  3 2015-02-23 FALSE FALSE  TRUE
5:  3 2015-02-23  TRUE FALSE FALSE

请注意,fread() 已自动识别布尔列。

聚合

library(data.table)
setDT(df)[, lapply(.SD, any), by = .(id, Date)]
   id       Date   OB1   OB2   OB3
1:  1 2017-01-01  TRUE FALSE FALSE
2:  2 2006-01-05  TRUE FALSE FALSE
3:  2 2007-04-19 FALSE  TRUE FALSE
4:  3 2015-02-23  TRUE FALSE  TRUE

如果 OP 需要整数值 01 而不是逻辑值,则可以一次性创建这些值:

setDT(df)[, lapply(.SD, function(x) as.integer(any(x))), by = .(id, Date)]
   id       Date OB1 OB2 OB3
1:  1 2017-01-01   1   0   0
2:  2 2006-01-05   1   0   0
3:  2 2007-04-19   0   1   0
4:  3 2015-02-23   1   0   1

【讨论】:

  • Guau 谢谢!我会试试这段代码,看起来很棒
猜你喜欢
  • 2018-08-11
  • 2015-09-08
  • 1970-01-01
  • 2017-06-24
  • 2012-03-25
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多