将两个数据帧与一个区分列连接起来的一行代码?

One-liner to concatenate two data frames with a distinguishing column?

我经常发现自己创建了两个相似的数据框,我想将它们 rbind 放在一起,但要跟踪每一行来自哪个数据框,并使用不同的列。我的典型主题是

new_df <- rbind(
  cbind(df1, id="A"),
  cbind(df2, id="B")
)

它很好地折叠成一行以提高可读性,但感觉笨拙,我想做得更优雅。我宁愿避免在多行中分别为每个定义新列,如下所示:

df1$id <- "A"
df2$id <- "B"
new_df <- rbind(df1, df2)

虽然我知道你 可以 通过玩弄 $<- 使它成为单行的,这往往会使它的可读性比 cbind/rbind 上面的主题。这些行也不能保证是唯一的,所以我不能做我在其他地方看到的推荐的经典 mutate/ifelse 主题:

# 'value' is not necessarily unique in the below line
new_df <- cbind(df1, df2) %>% mutate(id = ifelse(something==value, "A", "B")

这个问题通常受到一个过程的启发,比如为 ggplot 添加一个分面变量 - 我已经从不同的过程中制作了两个数据框,但想使用需要一个分面列的分面来绘制它们。

什么是 rbind 两个数据帧的 R 友好方式,同时创建一个列来跟踪它们来自哪个数据帧?

使用 bind_rows

可能更容易
library(dplyr)
bind_rows(list(A = df1, B = df2), .id = 'id')

1) 我们可以像这样从基数 R 使用 rbind/Map。这可以使用任意数量的数据帧,尽管这里我们只显示两个。

do.call("rbind", Map(data.frame, id = c("A", "B"), list(BOD, 10 * BOD)))

2) 如果我们从命名列表 L 开始,那么基本 R 代码将如下所示。

L <- list(A = BOD, B = 10 * BOD)
do.call("rbind", Map(data.frame, id = names(L), L))

给予:

    id Time demand
A.1  A    1    8.3
A.2  A    2   10.3
A.3  A    3   19.0
A.4  A    4   16.0
A.5  A    5   15.6
A.6  A    7   19.8
B.1  B   10   83.0
B.2  B   20  103.0
B.3  B   30  190.0
B.4  B   40  160.0
B.5  B   50  156.0
B.6  B   70  198.0

3) 请注意,如果名称如图所示包含在内,那么仅一个普通的 rbind 就会用 unique-ified 标记这些行的来源。

rbind(A = BOD, B = 10 * BOD)

给予:

    Time demand
A.1    1    8.3
A.2    2   10.3
A.3    3   19.0
A.4    4   16.0
A.5    5   15.6
A.6    7   19.8
B.1   10   83.0
B.2   20  103.0
B.3   30  190.0
B.4   40  160.0
B.5   50  156.0
B.6   70  198.0