Как преобразовать Иерархический фрейм данных, используя распространение / Pivot или Reshape - PullRequest
0 голосов
/ 01 апреля 2020

В настоящее время я пытаюсь переформатировать библиотеку документов в нисходящем иерархическом формате. Столбец docFrom содержит документ более высокого уровня, а subDo c содержит документ более низкого уровня, причем родительский столбец представляет количество уровней вниз по документу, а 1 - документ вверху. Данные Docs представляют собой все строки и в настоящее время выглядят так: единственное отличие состоит в том, что subDo c содержит все уникальные строки, которые не отображаются в фиктивных данных, представьте их в качестве фактических имен для сетей, шоу и эпизодов.

    docFrom      subDoc           Parent  
    NA           Network 1        1 
    Network 1    TvShow 1         2
    Network 1    TvShow 2         2             
    Network 1    TvShow 3         2
    Network 1    TvShow 4         2 
    TvShow 1     Episode 1        3 
    TvShow 1     Episode 2        3 
    TvShow 2     Episode 1        3 
    TvShow 2     Episode 2        3 
    TvShow 3     Episode 1        3 
    TvShow 1     Episode 2        3 

Для целей визуализации я хочу преобразовать это в

  1          2         3 
  Network 1  TvShow 1  Episode 1 
  Network 1  TvShow 1  Episode 2
  Network 1  TvShow 2  Episode 1 
  Network 1  TvShow 2  Episode 2 
  Network 1  TvShow 3  Episode 1 
  Network 1  TvShow 3  Episode 2 

, используя df <- reshape(Docs,idvar = "docFrom", timevar = "Parent", direction = "wide"), не сработало, и не сработало

df <- spread(Docs, Parent, subDoc)

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

Ответы [ 2 ]

1 голос
/ 01 апреля 2020

Мы решим проблему с помощью комбинации базы R и пакета sqldf(). Мы можем использовать столбец Parent, чтобы разделить данные на 3 кадра данных и объединить два результирующих кадра данных, где Parent - это 2 или 3 по имени телешоу.

textFile <- "docFrom  |subDoc   |Parent  
NA       |Network 1|1 
Network 1|TvShow 1 |2
Network 1|TvShow 2 |2             
Network 1|TvShow 3 |2
Network 1|TvShow 4 |2 
TvShow 1 |Episode 1|3 
TvShow 1 |Episode 2|3 
TvShow 2 |Episode 1|3 
TvShow 2 |Episode 2|3 
TvShow 3 |Episode 1|3 
TvShow 1 |Episode 2|3"

data <- read.csv(text = textFile,sep="|",stringsAsFactors = FALSE)
splitVar <- as.factor(data$Parent)
groupedData <- split(data,splitVar)

# second frame in list contains networks & shows
shows <- groupedData[[2]][-3]
colnames(shows) <- c("Network","Show")

# third frame in list contains shows and episodes
episodes <- groupedData[[3]][-3]
colnames(episodes) <- c("Show","Episode")

# use sqldf to join shows with episodes, since the shows data frame
# also includes the network names
library(sqldf)
sqlstmt <- "select s.Network, e.Show, e.Episode from shows s, episodes e where s.Show = e.Show"
result <- sqldf(sqlstmt)
result

... и вывод:

> result
    Network      Show   Episode
1 Network 1 TvShow 1  Episode 1
2 Network 1 TvShow 1  Episode 2
3 Network 1 TvShow 1  Episode 2
4 Network 1 TvShow 2  Episode 1
5 Network 1 TvShow 2  Episode 2
6 Network 1 TvShow 3  Episode 1
> 

dplyr версия

Мы можем использовать dplyr::inner_join() для достижения sh того же фрейма данных, к которому мы присоединяемся сделано с sqldf(). После того, как мы разбили входящие данные на отдельные фреймы данных по значению Parent, извлеченные из списка для создания фреймов данных shows и episodes и переименовали столбцы, мы объединяем два фрейма данных следующим образом.

# dplyr version
library(dplyr)
shows %>% inner_join(episodes, by = "Show")

... и вывод:

> shows %>% inner_join(episodes, by = "Show")
    Network      Show   Episode
1 Network 1 TvShow 1  Episode 1
2 Network 1 TvShow 1  Episode 2
3 Network 1 TvShow 1  Episode 2
4 Network 1 TvShow 2  Episode 1
5 Network 1 TvShow 2  Episode 2
6 Network 1 TvShow 3  Episode 1
> 
0 голосов
/ 01 апреля 2020

Полагаю, лучший совет здесь - сначала разделить Docs на 2 разных набора, TVShows и Episodes, например, TvShows = filter(Docs, stringr::str_detect("TvShow"))

Удалить родительский столбец, настроить имена столбцов и затем full_join им.

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