有没有一种方法可以在数据框中绑定不同数量的行?

Is there a method to bind varying numbers of rows inside a dataframe?

我有一个大型数据框,其中包含 3 列,分别命名为 IDxy。有一些 "ID" 出现不止一次(可以是任意次数),通常 "x" 和 "y" 的值是不同的,只是 "y" 可以是NA 超过一个重复的 "ID"。我的目标是获得一个数据框,其中每个 ID 只出现一次,但可能重复项的 x 和 y 值是额外的新列。这是一个简单的例子:

ID    x    y
 a    1    NA
 b    2    6
 a    3    7
 b    4    NA
 b    5    NA

这个 table 应该变成以下形式:

ID    x1    y1    x2    y2    x3    y3
 a     1    NA     3     7    NA    NA
 b     2     6     4    NA     5    NA

附加列的顺序无关紧要,只要 x 和 y 对仍然可识别即可。

我最大的问题是我需要将它应用于具有数千个不同 ID 的数据框,但到目前为止我找不到或无法编写可以自动执行此操作的函数。

到目前为止,最接近我的目标的是使用 unlist()。例如。只查看带有 ID = "a" 的行并将它们分配给新的数据框 A,我可以使用

unlist( append(distinct(A, ID), unlist(select(A, x, y))) )

但我无法将其更普遍地应用于整个数据框。

我也研究了一些将特定行连接或合并在一起的方法,但我无法解决所需附加列数量不同的问题。

谢谢!!

这正在重塑您的数据。您需要一个 time 变量。我们可以将 ave 函数与行中的序列一起使用。 (我使用了 x,您可以使用任何非因子变量或简单地使用 1:nrow(df))。然后我们 reshape 到 wide

在基础 R 中你可以这样做:

  reshape(transform(df,time=ave(x,ID,FUN=seq_along)),idvar = "ID",dir="wide",sep="")
  ID x1 y1 x2 y2 x3 y3
1  a  1 NA  3  7 NA NA
2  b  2  6  4 NA  5 NA

由于data.tabledcast需要多个value.var,所以可以用dcast

来完成
library(data.table)
dcast(setDT(df1), ID ~ rowid(ID), value.var = c("x", "y"), sep="")
#  ID x1 x2 x3 y1 y2 y3
#1:  a  1  3 NA NA  7 NA
#2:  b  2  4  5  6 NA NA

tidyverse中,这可以用pivot_wider来完成(来自tidyr的开发版本)

library(tidyverse)
df1 %>% 
   group_by(ID) %>%
   mutate(rn = row_number()) %>%
   pivot_wider(names_from = rn, values_from = c(x, y))
# A tibble: 2 x 7
#   ID      x_1   x_2   x_3   y_1   y_2   y_3
#  <chr> <int> <int> <int> <int> <int> <int>
#1 a         1     3    NA    NA     7    NA 
#2 b         2     4     5     6    NA    NA

数据

df1 <- structure(list(ID = c("a", "b", "a", "b", "b"), x = 1:5, y = c(NA, 
6L, 7L, NA, NA)), class = "data.frame", row.names = c(NA, -5L
))