#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! 😉