Как преобразовать набор данных года актера в набор данных года страны в R - PullRequest
1 голос
/ 15 апреля 2020

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

dt_initial <- data.frame(actor=c("Actor1","Actor1", "Actor2","Actor3"),year=c(2017,2018,2019,2020),
              country=c("Country1", "Country1", "Country1, Country2", "Country1, Country2, Country3"),
              amount=c(10,20,70,90))

> dt_initial
   actor year                      country amount
1 Actor1 2017                     Country1     10
2 Actor1 2018                     Country1     20
3 Actor2 2019           Country1, Country2     70
4 Actor3 2020 Country1, Country2, Country3     90

Я хотел бы преобразовать этот набор данных в набор данных страны-года, в котором у меня будет ряд для каждой страны. Кроме того, я хотел бы, чтобы переменная «сумма» была разделена на число стран, указанных в каждой строке из исходного набора данных. Таким образом, мой последний набор данных будет

dt_final <- data.frame(actor=c("Actor1", "Actor1","Actor2","Actor3", "Actor2", "Actor3", "Actor3"),year=c(2017, 2018, 2019,2020, 2019, 2020, 2020),
              country=c("Country1", "Country1", "Country1", "Country1",  "Country2", "Country2", "Country3"),
              amount=c(10, 20,35,30, 35, 30, 30))
> dt_final
   actor year  country amount
1 Actor1 2017 Country1     10
2 Actor1 2018 Country1     20
3 Actor2 2019 Country1     35
4 Actor3 2020 Country1     30
5 Actor2 2019 Country2     35
6 Actor3 2020 Country2     30
7 Actor3 2020 Country3     30

Большое спасибо заранее за вашу помощь!

Ответы [ 2 ]

2 голосов
/ 15 апреля 2020

Вот базовое решение R

fn <- function(v) {
  u <- unlist(strsplit(as.character(v$country),", "))
  transform(do.call(rbind,c(make.row.names = FALSE, replicate(length(u),v,simplify = FALSE))),
            country = u, 
            amount = amount/length(u))
}
dt_out <- do.call(rbind,
                  c(make.row.names = FALSE, 
                    lapply(split(dt_initial,seq(nrow(dt_initial))), 
                           fn)))

такое, что

> dt_out
   actor year  country amount
1 Actor1 2017 Country1     10
2 Actor1 2018 Country1     20
3 Actor2 2019 Country1     35
4 Actor2 2019 Country2     35
5 Actor3 2020 Country1     30
6 Actor3 2020 Country2     30
7 Actor3 2020 Country3     30
1 голос
/ 15 апреля 2020

Мы можем получить данные в разные строки, используя separate_rows, group_by каждая actor и разделить amount на количество строк в каждой группе.

library(dplyr)

dt_initial %>%
   mutate(row = row_number()) %>%
   tidyr::separate_rows(country, sep = ", ") %>%
   group_by(row) %>%
   mutate(amount = amount/n()) %>%
   ungroup %>%
   select(-row)

#   actor   year country  amount
#  <fct>  <dbl> <chr>     <dbl>
#1 Actor1  2017 Country1     10
#2 Actor1  2018 Country1     20
#3 Actor2  2019 Country1     35
#4 Actor2  2019 Country2     35
#5 Actor3  2020 Country1     30
#6 Actor3  2020 Country2     30
#7 Actor3  2020 Country3     30
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...