Как исправить 'Ошибка в if (is.character (txt) && length (txt) .....' 'при использовании purrr :: map () - PullRequest
0 голосов
/ 16 апреля 2019

Я использовал jsonlite, чтобы разбить некоторые вложенные JSON в импортированном CSV-файле. У меня был большой успех при использовании purrr::map() для создания списка фреймов данных и соответствующей их обработки. После того, как мне пришлось на некоторое время вручную удалить строки, если они не содержали содержимого JSON в определенных столбцах, я в итоге использовал apply(), чтобы просмотреть основную таблицу и удалить все, что содержит «[]» (эквивалент отсутствия записи в мой файл). После этого я не могу использовать функцию purrr::map() без сообщения об ошибке:

Error in if (is.character(txt) && length(txt) == 1 && nchar(txt, type = 
"bytes") <  : 
  missing value where TRUE/FALSE needed 

purrr::map() работает, только если я просто сбрасываю строки вручную, но когда я пытаюсь разбить столбец JSON после удаления этих строк с помощью apply, я получаю эту ошибку.

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

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

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

library(ridge)
library(glmnet)
library(ggplot2)
library(jtools)
library(readr)
options(scipen = 999)

#import data
movies <- read_csv("tmdb-5000-movie-dataset/tmdb_5000_movies.csv")
credits <- read_csv("tmdb-5000-movie-dataset/tmdb_5000_credits.csv")

#clean data, drop columns with empty "cast" or "crew"
drop.rows <- c(2602, 3662, 3671, 3972, 3978, 3993, 4010, 4069, 4106, 4119, 
4124, 4248, 4294, 4306, 
           4315, 4323, 4386, 4401, 4402, 4406, 4414, 4432, 4459, 4492, 4505, 4509, 4518, 4551, 
           4554, 4563, 4565, 4567, 4570, 4572, 4582, 4582, 4584, 4590, 4612, 4617, 4618, 4623, 
           4634, 4639, 4639, 4645, 4658, 4663, 4675, 4680, 4682, 4686, 4690, 4699, 4711, 4713, 
           4715, 4717, 4738, 4758, 4756, 4798, 4802)
movies <- movies[-c(drop.rows), ]
credits <- credits[-c(drop.rows), ]



#JSON processing
library(jsonlite)

#cast from JSON (credits$cast)
cast <- purrr::map(credits$cast, jsonlite::fromJSON)

#crew from JSON (credits$crew)
crew <- purrr::map(credits$crew, jsonlite::fromJSON)

#create list of "stars"
starring <- vector("character", length(cast))
index <- 1

#create list of "name" of first actor in each movie
for (i in cast) {
  #print(i[1,6])
  starring[[index]] <- i[1,6]
  index <- index + 1
}

#add "starring" column to movies dataframe
movies$starring <- starring





#create list of "directors"
director <- vector("character", length(crew))
index <- 1

#create list of "names" that correspond with rows that contain the "job" 
Director
for (i in crew) {
  director[[index]] <-i[,6][which( i["job"] == "Director" )][1]
  index <- index + 1
}

#add director column to movies dataframe
movies$director <- director




#genre from JSON 
genres <- purrr::map(movies$genres, jsonlite::fromJSON)

genre <- vector("character", length(genres))
index <- 1

for (i in genres) {
  #print(i[1,6])
  genre[[index]] <- i[1,2]
  index <- index + 1
}

movies$genre <- genre




#drop unneccessary columns to make things easier
drops <- c("genres","homepage", "id", "keywords", "overview", "status", 
"tagline", "spoken_languages", "original_title")
movies <- movies[ , !(names(movies) %in% drops)]

#further cleaning, drop rows with empty JSON and rows with budget and 
revenue < 30 (clear errors)
movies <- movies[apply(movies[c(1, 8)],1,function(z) !any(z<30)),]



#####################################################################
#THIS IS WHERE I ATTEMPT TO DROP THE ROWS

movies <- movies[apply(movies[c(4)],1,function(z) !any(z=="[]")),]




#####################################################################


#####################################################################
#I THEN GET THE ERROR MESSAGE HERE

#create production company column from JSON
productionco <- purrr::map(movies$production_companies, jsonlite::fromJSON)

#####################################################################
...