Применить функцию к сгруппированному фрейму данных R - PullRequest
0 голосов
/ 31 января 2020

Я пытаюсь разделить фрейм данных по группе, а затем применить функцию, которая создаст несколько отдельных списков или фреймов данных.

Например, разделить данные ниже по id, а затем создать отдельные списки или фреймы данных. для каждого 60-дневного периода.

id <- rep(1:5, each = 365)
date <- rep(seq(as.Date('2019-01-01'), as.Date('2019-12-31'), 'day'), 5)
x <- rnorm(1825)
y <- rnorm(1825)

df <- data.frame(id, date, x, y) 

Я пытался использовать group_split или split в сочетании с seq.int, и я могу заставить это работать только с 1 идентификатором, используя этот

df2 <- df %>% 
  filter(id == 1)

data <- list()

data <- lapply(
  seq(1,length(df2$x)-(60-1)) #For the number of days - n - 1 
  ,function(i) {
    data[[i]] <- list('x'=df2$x[seq.int(i,i+(60-1))] 
                            ,'y' = df2$y[seq.int(i,i+(60-1))])
  })

Поэтому конечный вывод будет либо группой списков, таких как вывод сверху, либо вложенным фреймом данных

ID |last_date  | data
1  | 2019-12-31| [60 x 3]
1  | 2019-12-30| [60 x 3]
1  | 2019-12-29| [60 x 3]

1 Ответ

1 голос
/ 31 января 2020

Вы можете попробовать split, затем вложенный lapply:

nested <- do.call(rbind, lapply(split(df, df$id), function(x) 
  {
    do.call(rbind, lapply(1:60, function(y) 
    {
      z <- x[y + 0:59, ]
      tibble(id = z$id[1], last_date = max(z$date), data = list(list(x = z$x, y = z$y))) 
    }))
  }))

Это дает вложенный фрейм данных, где каждая строка имеет идентификатор, дату и список значений x и y:

nested
#> # A tibble: 300 x 3
#>       id last_date  data            
#>  * <int> <date>     <list>          
#>  1     1 2019-03-01 <named list [2]>
#>  2     1 2019-03-02 <named list [2]>
#>  3     1 2019-03-03 <named list [2]>
#>  4     1 2019-03-04 <named list [2]>
#>  5     1 2019-03-05 <named list [2]>
#>  6     1 2019-03-06 <named list [2]>
#>  7     1 2019-03-07 <named list [2]>
#>  8     1 2019-03-08 <named list [2]>
#>  9     1 2019-03-09 <named list [2]>
#> 10     1 2019-03-10 <named list [2]>
#> # ... with 290 more rows

Так что вы можете сделать

nested$data[1]
#> [[1]]
#> [[1]]$`x`
#>  [1] -0.186294037  0.407488434  0.521475261 -0.422258233  1.664796990 -0.316456771
#>  [7]  0.182665242 -0.484338801 -0.192649909  0.873081270 -0.990823599  1.144433027
#> [13]  0.051712197  1.859142715  0.990093007 -0.001696676 -1.562290916 -0.476260992
#> [19]  0.975347849  0.084371694 -1.282503593  2.051669409 -0.703195871  0.350304665
#> [25] -0.324944027  1.640499226  1.197330101 -0.105973265  0.554276498  0.297189917
#> [31]  0.293502194  0.634043164 -0.322015474 -0.058275122 -0.410971343  0.309959510
#> [37] -1.379586045 -0.768224289  1.526995932 -0.981805376 -1.012230771 -0.364945605
#> [43]  1.130352216  1.131795697 -0.055765142 -1.517343421  0.282312602 -1.494675521
#> [49] -1.655192256  0.384317093 -0.518346889  0.828578708  1.071474898  1.365419431
#> [55] -0.348300271 -0.190303801  0.618120362 -0.969343280 -0.751382466  0.097511207
#> 
#> [[1]]$y
#>  [1]  0.241841347 -0.433619020  0.341544232 -0.443052330  1.418478139 -1.003223330
#>  [7] -1.155966273 -0.862516431 -0.122768860 -0.082490747  0.456701203  0.405343576
#> [13] -2.106437081  0.645778514 -1.169678108 -1.451066029 -0.008333085  0.197081852
#> [19] -2.159107679 -2.167901928  0.062350030  0.507316009  0.077904318 -0.067838411
#> [25] -0.134667541  0.148749420 -0.463352528  0.293970945 -1.312431997  1.548834167
#> [31] -0.081291696  2.459888522 -0.105747872 -0.662130765 -1.127856102  0.037625236
#> [37]  0.378573145  0.574886376 -0.458236747 -1.402287567  0.703899240  1.532274574
#> [43]  0.654629245  0.762259424  0.001331954  0.619991076 -0.909183901  0.031380382
#> [49] -0.017907535  0.092751553  0.376905305 -1.104308942 -1.309079449 -0.252910625
#> [55]  0.991728742  0.217956094 -0.051243518  0.191618312 -0.633832253 -1.466263740
...