我知道从长格式到宽格式有很多指南。例如,请参见here。
但是,我相信我有一个独特的案例,或者至少是一个我无法在堆栈溢出中找到答案的案例,尽管也许我的语言不适合我的问题。我将用数据描述我的问题。我有一个看起来像这样的数据框:
> my.df <- data.frame(ID=rep(c("A","B","C"), 3), TIME=rep(1:9, each=1), X=1:9, Y=10:18)
> my.df
ID TIME X Y
1 A 1 1 10
2 B 2 2 11
3 C 3 3 12
4 A 4 4 13
5 B 5 5 14
6 C 6 6 15
7 A 7 7 16
8 B 8 8 17
9 C 9 9 18
我想从长格式转换为宽格式,但重要的是我想保留time列中包含的唯一信息,并且不希望它散布到列名中。我想创建多个具有重复ID的时间列,并在该列旁边存储相应的X和Y数据。
请参见下面的期望输出:
> my.df <- data.frame(ID=c("A","B","C"), TIME_1=c(1,2,3),X_1 = c(1,2,3), Y_1= c(10,11,12),
+ TIME_2 = c(4,5,6),X_2 = c(4,5,6),Y_2 = c(13,14,15),
+ TIME_3 = c(7,8,9),X_3 = c(7,8,9),Y_3 = c(16,17,18))
> my.df
ID TIME_1 X_1 Y_1 TIME_2 X_2 Y_2 TIME_3 X_3 Y_3
1 A 1 1 10 4 4 13 7 7 16
2 B 2 2 11 5 5 14 8 8 17
3 C 3 3 12 6 6 15 9 9 18
这可能吗?
我的实际数据帧要大得多,并且TIME列包含无法放入列名的唯一日期,这就是为什么要将这些信息存储在新列中的原因。我知道我最多只能有4个重复的ID值,因此我不必担心会创建过多的列。
答案 0 :(得分:1)
使用基数R中的reshape
。ave
标识示例数据中的三个随后的seq
值。
reshape(transform(my.df, t2=with(my.df, ave(TIME, ID, FUN=seq))), idvar=c("ID"),
timevar=c("t2"), direction="wide")
# ID TIME.1 X.1 Y.1 TIME.2 X.2 Y.2 TIME.3 X.3 Y.3
# 1 A 1 1 10 4 4 13 7 7 16
# 2 B 2 2 11 5 5 14 8 8 17
# 3 C 3 3 12 6 6 15 9 9 18
答案 1 :(得分:0)
我们可以使用dcast
中的data.table
library(data.table)
dcast(setDT(my.df), ID ~ rowid(ID), value.var = c("TIME", "X", "Y"))
# ID TIME_1 TIME_2 TIME_3 X_1 X_2 X_3 Y_1 Y_2 Y_3
#1: A 1 4 7 1 4 7 10 13 16
#2: B 2 5 8 2 5 8 11 14 17
#3: C 3 6 9 3 6 9 12 15 18
或使用tidyverse
library(dplyr)
library(tidyr)
my.df %>%
mutate(ind = rowid(ID)) %>%
pivot_wider(names_from = ind, values_from = c(TIME, X, Y))
# A tibble: 3 x 10
# ID TIME_1 TIME_2 TIME_3 X_1 X_2 X_3 Y_1 Y_2 Y_3
# <fct> <int> <int> <int> <int> <int> <int> <int> <int> <int>
#1 A 1 4 7 1 4 7 10 13 16
#2 B 2 5 8 2 5 8 11 14 17
#3 C 3 6 9 3 6 9 12 15 18
如果我们需要以特定方式对列进行排序
my.df %>%
mutate(ind = rowid(ID)) %>%
pivot_wider(names_from = ind, values_from = c(TIME, X, Y)) %>%
select(ID, order(readr::parse_number(names(.)[-1])) + 1)
# A tibble: 3 x 10
# ID TIME_1 X_1 Y_1 TIME_2 X_2 Y_2 TIME_3 X_3 Y_3
# <fct> <int> <int> <int> <int> <int> <int> <int> <int> <int>
#1 A 1 1 10 4 4 13 7 7 16
#2 B 2 2 11 5 5 14 8 8 17
#3 C 3 3 12 6 6 15 9 9 18