R: Как перенести последнее наблюдаемое значение вперед в пределах одной и той же единицы наблюдения - PullRequest
0 голосов
/ 10 января 2020

У меня есть небольшая проблема с R и тидиверсом, которую, к сожалению, я не могу решить.

Скажем, у нас ежеквартальные наблюдения за тремя магазинами (в минимальном рабочем примере значения действительно не имеют значения, важны NA и несколько почтовых индексов в последнем столбце).

library(tidyverse)



mydf <- tribble(~shop, ~quarter, ~revenue, ~postcode,  "Shop A",1, 100, NA, "Shop A",2, 210, NA,"Shop A",3, 50 , NA,  "Shop A",4, 100, 1000,  "Shop B", 1, 40, NA,  "Shop B", 2, 80, NA,   "Shop B", 3, 20, NA,   "Shop B", 4, 40, NA,  "Shop C", 1, 20, 2011,  "Shop C", 2, 20, NA,  "Shop C", 3, 30, NA,  "Shop C", 4, 25, NA,)

Магазин A имеет только один почтовый индекс в четвертом квартале. Магазин B не имеет никакого почтового индекса, а магазин C имеет только почтовый индекс в первом квартале, см. Mydf.

Мы можем с уверенностью предположить, что почтовые индексы для магазинов не меняются, поэтому мы можем перенести последнее наблюдаемое значение, т.е. почтовый индекс.

Я использую для этого tidyverse, команда выглядит следующим образом.

mydf %>% fill(postcode, .direction="down")
mydf %>% fill(postcode, .direction="up")

К сожалению, R, похоже, не очень заботится о единиц измерения, он просто выбирает найденные им почтовые индексы и переносит это значение вперед, в этом примере через различных магазинов.

Что я хотел бы в конечном итоге - это заполнить почтовые индексы для Магазины A и C, а не для B, для которого мне пришлось бы вручную искать почтовый индекс.

(в наборе данных, с которым я работаю, есть тысячи аберраций ("магазинов"), так что это будет хороший способ минимизировать рабочую нагрузку.)

Я довольно плохо знаком с R, поэтому, пожалуйста, не обращайте на меня внимания sh.

Заранее спасибо за любые подсказки по решению.

Дэвид

Ответы [ 2 ]

2 голосов
/ 10 января 2020

Базовое решение R:

library(tibble)
mydf <- tribble(~shop, ~quarter, ~revenue, ~postcode,  "Shop A",1, 100, NA, "Shop A",2, 210, NA,"Shop A",3, 50 , NA,  "Shop A",4, 100, 1000,  "Shop B", 1, 40, NA,  "Shop B", 2, 80, NA,   "Shop B", 3, 20, NA,   "Shop B", 4, 40, NA,  "Shop C", 1, 20, 2011,  "Shop C", 2, 20, NA,  "Shop C", 3, 30, NA,  "Shop C", 4, 25, NA,)


list_df <- split(mydf, mydf$shop)
semi_filled <- lapply(list_df, function(x) {
  unq <- unique(x$postcode)
  x$postcode <- if (all(is.na(unq))) NA else unq[!is.na(unq)]
  x
})

Reduce(rbind, semi_filled)
#> # A tibble: 12 x 4
#>    shop   quarter revenue postcode
#>    <chr>    <dbl>   <dbl>    <dbl>
#>  1 Shop A       1     100     1000
#>  2 Shop A       2     210     1000
#>  3 Shop A       3      50     1000
#>  4 Shop A       4     100     1000
#>  5 Shop B       1      40       NA
#>  6 Shop B       2      80       NA
#>  7 Shop B       3      20       NA
#>  8 Shop B       4      40       NA
#>  9 Shop C       1      20     2011
#> 10 Shop C       2      20     2011
#> 11 Shop C       3      30     2011
#> 12 Shop C       4      25     2011
2 голосов
/ 10 января 2020

Использование group_by и затем заполнение должно работать. Он будет заполнять только один и тот же почтовый индекс для каждого отдельного магазина. Проблема с вашими примерами данных в том, что в магазине B нет никаких почтовых индексов.

Использование .direction = 'downup' должно заполнять почтовый индекс независимо от того, где он находится в столбце почтового индекса. Если это всегда первое наблюдение, в этом не должно быть необходимости.

library(tidyverse)

mydf <- tribble(~shop, ~quarter, ~revenue, ~postcode,  "Shop A",1, 100, NA, "Shop A",2, 210, NA,"Shop A",3, 50 , NA,  "Shop A",4, 100, 1000,  "Shop B", 1, 40, NA,  "Shop B", 2, 80, NA,   "Shop B", 3, 20, NA,   "Shop B", 4, 40, NA,  "Shop C", 1, 20, 2011,  "Shop C", 2, 20, NA,  "Shop C", 3, 30, NA,  "Shop C", 4, 25, NA,)

mydf %>% 
  group_by(shop) %>% 
  fill(postcode, .direction = 'downup')
#> # A tibble: 12 x 4
#> # Groups:   shop [3]
#>    shop   quarter revenue postcode
#>    <chr>    <dbl>   <dbl>    <dbl>
#>  1 Shop A       1     100     1000
#>  2 Shop A       2     210     1000
#>  3 Shop A       3      50     1000
#>  4 Shop A       4     100     1000
#>  5 Shop B       1      40       NA
#>  6 Shop B       2      80       NA
#>  7 Shop B       3      20       NA
#>  8 Shop B       4      40       NA
#>  9 Shop C       1      20     2011
#> 10 Shop C       2      20     2011
#> 11 Shop C       3      30     2011
#> 12 Shop C       4      25     2011

Создано в 2020-01-10 пакетом Представить (v0.3.0 )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...