在R中的一列上展开

在R中的一列上展开,r,tidyr,R,Tidyr,假设我有这样一个数据框: data.frame(x = c(1,1,1,3,3,3),y = c(12,32,43,16,32,65)) data.frame(x = c(1, 3), y_1 = c(12,16), y_2 =c(32, 32),y_3= c(43, 65)) 我想把它转换成这样的数据帧: data.frame(x = c(1,1,1,3,3,3),y = c(12,32,43,16,32,65)) data.frame(x = c(1, 3), y_1 = c(12

假设我有这样一个数据框:

data.frame(x = c(1,1,1,3,3,3),y = c(12,32,43,16,32,65))
data.frame(x = c(1, 3), y_1 =  c(12,16), y_2 =c(32, 32),y_3= c(43, 65))
我想把它转换成这样的数据帧:

data.frame(x = c(1,1,1,3,3,3),y = c(12,32,43,16,32,65))
data.frame(x = c(1, 3), y_1 =  c(12,16), y_2 =c(32, 32),y_3= c(43, 65))
基本上为每个唯一的x值分散y值。我曾尝试使用tidyr来实现这一点,但不太清楚它是如何工作的。有什么想法吗


谢谢。

这里有一个
数据。表
解决方案:

library(data.table)

dat = as.data.table(df) # or setDT to convert in place

dat[, obs := paste0('y_', 1:.N), by=x]
dcast(dat, x ~ obs, value.var="y")

#   x y_1 y_2 y_3
#1: 1  12  32  43
#2: 3  16  32  65

即使所有
x

的行数不相同,这也会起作用。我们可以使用
聚合
,然后使用
cSplit
splitstackshape
包强制到数据帧

library(splitstackshape)
df1 <- aggregate(y ~ x, df, paste, collapse = ',')
df1 <- cSplit(df1, 'y', ',', direction = 'wide')
#   x y_1 y_2 y_3
#1: 1  12  32  43
#2: 3  16  32  65
库(splitstackshape)

df1Sotos使用
aggregate
给出的答案特别优雅,但以下使用
重塑
的方法也可能具有指导意义:

df <- data.frame(x = c(1,1,1,3,3,3),y = c(12,32,43,16,32,65))
df[,"time"] <- rep(1:3, 2)
wide_df <- reshape(df, direction="wide", timevar="time", idvar="x")

dfdplyr/tidyr的一个选项

library(dplyr)
library(tidyr)
df1 %>% 
    group_by(x) %>% 
    mutate(n = paste("y", row_number(), sep="_")) %>%
    spread(n,y)
#     x   y_1   y_2   y_3
#   (dbl) (dbl) (dbl) (dbl)
#1     1    12    32    43
#2     3    16    32    65

不错。还可以插入一个
transform()
调用,而不必改变原始数据
重塑(transform(df,time=ave(y,x,FUN=seq_-along)),direction=“wide”,timevar=“time”,idvar=“x”,sep=“”)