Комбинируйте длинноформатные кадры данных различной длины и преобразуйте их в широкий формат

#r #time-series #data-manipulation #data-cleaning #panel-data

Вопрос:

Я хочу объединить кадры данных в длинном формате с разной длиной из-за time переменной (несбалансированные данные панели).:

 set.seed(63) #function to create a data frame that includes id, time and x func1 lt;- function (size=5) {  x=sample(c(0,1), 1)  data.frame(time=1:size, x=x)}   #function to row combine data frames func2 lt;- do.call("rbind", Map(function(x,y) {  data.frame(id=x, func1(y))  }, 1:5, 5))   #Sample 10 observations to create imbalanced panel data dd lt;- func2[sample(nrow(func2), 10), ]  fd lt;- dd[with(dd, order(id, time)),] gt; fd  id time x 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 0 5 1 5 0 10 2 5 1 13 3 3 0 17 4 2 0 18 4 3 0 21 5 1 0  

В конце концов, я хочу преобразовать его в широкий формат и заполнить пропущенными ячейками на x основе time переменной . Что-то вроде этого:

 id x.time1 x.time2 x.time3 x.time4 x.time5  1 0 0 0 0 0 2 NA NA NA NA 1 3 NA NA 0 NA NA 4 NA 0 0 NA NA 5 0 NA NA NA NA  

Комментарии:

1. Да, это опечатка. Я исправил это.

Ответ №1:

С помощью data.table

 library(data.table) dcast(setDT(fd), id ~ paste0('x.time', time), value.var = 'x')  

-выход

 id x.time1 x.time2 x.time3 x.time4 x.time5 1: 1 0 0 0 0 0 2: 2 NA NA NA NA 1 3: 3 NA NA 0 NA NA 4: 4 NA 0 0 NA NA 5: 5 0 NA NA NA NA  

Ответ №2:

Возможное решение:

 library(tidyverse)  fd lt;- data.frame(  id = c(1L, 1L, 1L, 1L, 1L, 2L, 3L, 4L, 4L, 5L),  time = c(1L, 2L, 3L, 4L, 5L, 5L, 3L, 2L, 3L, 1L),  x = c(0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L) )  fd %gt;%   pivot_wider(id, names_from = time, values_from = x, names_prefix = "x.time")  #gt; # A tibble: 5 × 6 #gt; id x.time1 x.time2 x.time3 x.time4 x.time5 #gt; lt;intgt; lt;intgt; lt;intgt; lt;intgt; lt;intgt; lt;intgt; #gt; 1 1 0 0 0 0 0 #gt; 2 2 NA NA NA NA 1 #gt; 3 3 NA NA 0 NA NA #gt; 4 4 NA 0 0 NA NA #gt; 5 5 0 NA NA NA NA  

Комментарии:

1. Спасибо тебе @Paul! Я поддержал ваш ответ, но принял data.table решение akrun, потому что, предположительно, это быстрее, чем tidyverse

2. Добро пожаловать, @cliu! И нет проблем: я здесь для того, чтобы учиться, а не для того, чтобы получить репутацию StackOverflow! 😉