Использование str_split для заполнения строк во фрейме данных диапазонами номеров и несколькими числами - PullRequest
0 голосов
/ 24 февраля 2020

У меня есть фрейм данных с названиями культур и соответствующими кодами ФАО. К сожалению, некоторые категории культур, такие как «другие зерновые культуры», имеют несколько кодов ФАО, диапазоны кодов ФАО или, что еще хуже, - несколько диапазонов кодов ФАО.

Фрагмент кадра данных с различными форматами для кодов ФАО.

> FAOCODE_crops
      SPAM_full_name                          FAOCODE
1              wheat                               15
2               rice                               27
8      other cereals 68,71,75,89,92,94,97,101,103,108
27   other oil crops                  260:310,312:339
31 other fibre crops                          773:821

Использование следующего кода успешно разбивает эти числа,

unlist(lapply(unlist(strsplit(FAOCODE_crops$FAOCODE, ",")), function(x) eval(parse(text = x))))
[1]  15  27  56  44  79  79  83  68  71  75  89  92  94  97 101 103 108

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

> FAOCODE_crops$FAOCODE <- unlist(lapply(unlist(strsplit(MAPSPAM_crops$FAOCODE, ",")), function(x) eval(parse(text = x))))
Error in `$<-.data.frame`(`*tmp*`, FAOCODE, value = c(15, 27, 56, 44,  : 
  replacement has 571 rows, data has 42

Я полностью понимаю, почему он не слился успешно, но я не могу найти способ заполнить таблицу новой строкой для каждого FAOCODE, как показано ниже:

SPAM_full_name                          FAOCODE
1              wheat                               15
2               rice                               27
8      other cereals                               68
8      other cereals                               71
8      other cereals                               75
8      other cereals                               89

И так далее ...

Любая помощь очень ценится!

1 Ответ

0 голосов
/ 25 февраля 2020

Мы можем использовать separate_rows для разделения ,. После этого мы можем l oop через FAOCODE, используя map и ~eval(parse(text = .x)) для оценки диапазона номеров. В конечном итоге мы можем использовать unnest для расширения фрейма данных.

library(tidyverse)

dat2 <- dat %>%
  separate_rows(FAOCODE, sep = ",") %>%
  mutate(FAOCODE = map(FAOCODE, ~eval(parse(text = .x)))) %>%
  unnest(cols = FAOCODE)
dat2
# # A tibble: 140 x 2
#    SPAM_full_name FAOCODE
#    <chr>            <dbl>
#  1 wheat               15
#  2 rice                27
#  3 other cereals       68
#  4 other cereals       71
#  5 other cereals       75
#  6 other cereals       89
#  7 other cereals       92
#  8 other cereals       94
#  9 other cereals       97
# 10 other cereals      101
# # ... with 130 more rows

DATA

dat <- read.table(text = "      SPAM_full_name                          FAOCODE
1              wheat                               15
2               rice                               27
8      'other cereals' '68,71,75,89,92,94,97,101,103,108'
27   'other oil crops'                  '260:310,312:339'
31 'other fibre crops'                          '773:821'",
                  header = TRUE, stringsAsFactors = FALSE)
...