我有一个大型数据框,其中包含3列,分别为ID
,x
和y
。有一些“ 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
此表应变为以下形式:
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))) )
但是我不能将其更广泛地应用于整个数据帧。
我还研究了将特定行连接或合并在一起的一些方法,但是我无法解决所需的额外列数不同的问题。
谢谢!
答案 0 :(得分:3)
由于data.table
dcast
需要多个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
))
答案 1 :(得分:2)
这正在重塑您的数据。您需要一个time
变量。我们可以沿行使用带有序列的ave函数。 (我使用x,您可以使用任何非因变量或简单地使用1:nrow(df))。然后我们重塑到宽幅
在基数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