【问题标题】:Merge / Join data.tables per row每行合并/连接 data.tables
【发布时间】:2021-02-03 03:02:32
【问题描述】:

我有以下数据表,我想从所有三个数据表中制作一个数据表。

library(dplyr)
set.seed(123)

dt.Ger <- data.table(date = seq(as.Date('2020-01-01'), by = '1 day', length.out = 365),
                     Germany = rnorm(365, 2, 1), check.names = FALSE)
dt.Aut <- data.table(date = seq(as.Date('2020-01-01'), by = '1 day', length.out = 365),
                     Austria = rnorm(365, 4, 2), check.names = FALSE)
dt.Den <- data.table(date = seq(as.Date('2020-01-01'), by = '1 day', length.out = 365),
                     Denmark = rnorm(365, 3, 1), check.names = FALSE)

dt.Ger <- dt.Ger %>%
  mutate(month = format(date, '%b'), 
         date = format(date, '%d')) %>%
  tidyr::pivot_wider(names_from = date, values_from = Germany)

dt.Aut <- dt.Aut %>%
  mutate(month = format(date, '%b'), 
         date = format(date, '%d')) %>%
  tidyr::pivot_wider(names_from = date, values_from = Austria)

dt.Den <- dt.Den %>%
  mutate(month = format(date, '%b'), 
         date = format(date, '%d')) %>%
  tidyr::pivot_wider(names_from = date, values_from = Denmark)

现在我想将所有表链接在一起,即首先添加dt.Ger,然后可能添加两个空行,然后附加dt.Aut,现在再次添加两个空行,最后添加dt.Den。理想情况下,如果德国是第一个标题,然后是奥地利(在dt.Aut 之前的第二个空行中),然后是丹麦(在dt.Den 之前的第二个空行中),那就太好了。

所以我只有一个表作为回报。这张表应该是这样的(我只用 SnippingTool 做的,所以它只是用来解释):

编辑: 使用

l <- list(dt.Ger, dt.Aut, dt.Den)
l.result <- rbindlist(l)

屈服于:

而且我想获得一个额外的空间/行/行(在红色部分),其中写着德国、奥地利和丹麦。

【问题讨论】:

  • 我不太确定这是怎么回事。对我来说看起来像三个单独的表?要将它们合并到data.table 结构中(参见?rbindlist)还是将它们输出为HTML datatables
  • 我也不完全确定你想在这里实现什么,但我能想到的一个选项(取决于这个目标)是创建一个“国家”列并为每个表填充.然后使用bind_rows()将它们合并在一起
  • 为什么不直接使用 lapply 并将它们作为子列表?如果你真的想要它们作为 data.frames,你可以使用 sapply。这些也应该适用于你的 plot_ly 功能
  • @ismirsehregal 我现在可以将所有 3 个数据表与rbindlist() 合并/加入,但是如何在每个新数据表之前添加标题/标题或空行(带有标题/标题) ?我要在RShiny中输出一张数据表,所以3张数据表都得先合并。
  • @D.J 谢谢你的回答,但我不确定我应该在这里为FUN使用什么???

标签: r join merge data.table rows


【解决方案1】:

我仍然不确定,您想要实现什么 - 对我来说,您似乎最好使用 data.tables 列表。

此外,我改用dcast 而不是pivot_wider,所以你可以放弃tidyr / dplyr

但是,这是一种使用 rbindlist 在不同 data.tables 之间插入 NAs 的方法:

library(data.table)
set.seed(123)

dt.Ger <- data.table(date = seq(as.Date('2020-01-01'), by = '1 day', length.out = 365),
                     Germany = rnorm(365, 2, 1), check.names = FALSE)
dt.Aut <- data.table(date = seq(as.Date('2020-01-01'), by = '1 day', length.out = 365),
                     Austria = rnorm(365, 4, 2), check.names = FALSE)
dt.Den <- data.table(date = seq(as.Date('2020-01-01'), by = '1 day', length.out = 365),
                     Denmark = rnorm(365, 3, 1), check.names = FALSE)

# or rather date  ~ month?
dt.Ger[, c("month", "date") := list(format(date, '%b'), format(date, '%d'))]
dt.Ger <- dcast(dt.Ger, month ~ date, value.var = "Germany")

dt.Aut[, c("month", "date") := list(format(date, '%b'), format(date, '%d'))]
dt.Aut <- dcast(dt.Aut, month ~ date, value.var = "Austria")

dt.Den[, c("month", "date") := list(format(date, '%b'), format(date, '%d'))]
dt.Den <- dcast(dt.Den, month ~ date, value.var = "Denmark")

# use a list of data.tables:
recommended <- list(Germany = dt.Ger, Austria = dt.Aut, Denmark = dt.Den)

DT <- rbindlist(list(data.table(month = c("", "Germany")), dt.Ger, data.table(month = c("", "Austria")), dt.Aut, data.table(month = c("", "Denmark")), dt.Den), fill = TRUE) # [, V1 := NULL]
DT[,(names(DT)):= lapply(.SD, as.character), .SDcols = names(DT)]
for (j in seq_len(ncol(DT))){
  set(DT, which(is.na(DT[[j]])), j, "")
}

print(DT)

【讨论】:

  • 谢谢,这正是我想要的。还有一个问题。现在空单元格具有 NA 值。如果我在 RShiny 中将其打印为输出,那么我不想看到 NA 值。应该只是空单元格。这可能吗?
  • 目前您的大部分列是numeric。您需要将列类型更改为 character 才能通过,例如一个空字符串 ("")。
  • 是否可以仅将这些行更改为character
  • 据我所知这是不可能的。 data.tables 有列类。
  • 我不知道你的用例,但我真的建议使用 data.tables 列表而不是在单个 data.table 对象中插入标题信息。
猜你喜欢
  • 2012-12-17
  • 2013-03-06
  • 2012-10-27
  • 1970-01-01
  • 2017-06-29
  • 2011-12-16
  • 2021-04-20
  • 2021-07-29
  • 2010-09-10
相关资源
最近更新 更多