2016-09-18 1 views
1

У меня есть набор данных на основе событий и каждое событие имеет атрибуты в формате JSON, поэтому, например, упрощенная версия данных:Работы с многозначными атрибутами в R - создание столбцов для каждого атрибута

id event  attribute 
1 23  {'grades':43, 'school':'primary'} 
2 49  {} 
3 99  {'x':49, 'y':52, 'country':'Japan'} 
4 89  {'grades':56} 

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

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

d = data.frame(id = 1:4, 
       event =c(23, 49, 99, 89), 
       grades = c(43, NA, NA, 56), 
       school=c("primary", NA, NA, NA)) 

без ручного ввода его

второго/третьего обновление

Я ВИР tten это, что, кажется, работает, поэтому я думал, что я хотел бы поделиться, если есть более простой способ сделать это, пожалуйста, дайте мне знать:

library(jsonlite) 

#data input 
    id <- 1:4 
    event <- c(23,49,99,89) 
    attribute <- c("{'grades':43, 'school':'primary'}", "{}", "{'x':49, 'y':52, 'country':'Japan'}", "{'grades':56}") 

#format for fromJSON 
    attribute <- gsub("'", '"', attribute) 
    att <- lapply(attribute, fromJSON) 

#distinct attributes 
    att_names <- unique(unlist(lapply(att, names))) 

#store output in list list_atts 
    list_atts <- list() 

    for(i in 1:length(att_names)){ 
      j <- lapply(att, "[", paste(att_names[i])) 
      j <- lapply(j, function(x) ifelse(is.null(unlist(x)) == TRUE, NA, unlist(x))) # convert NULL to NA 
      list_atts[[i]] <- unlist(j) 
      names(list_atts)[i] <- paste(att_names[i]) 
    } 

Выход здесь:

> data.frame(list_atts, stringsAsFactors = FALSE) 
    grades school x y country 
1  43 primary NA NA <NA> 
2  NA <NA> NA NA <NA> 
3  NA <NA> 49 52 Japan 
4  56 <NA> NA NA <NA> 

ответ

2

Вы можете попробовать:

library(dplyr) 
library(tidyr) 
df %>% 
    mutate(to = strsplit(attribute, ",")) %>% 
    unnest(to) %>% 
    separate(to, into = c("l", "v"), sep = ":") %>% 
    mutate_at(vars(l, v), funs(gsub("[^[:alnum:]]", "", .))) %>% 
    spread(l, v, sep = "_") %>% 
    select(-attribute, -l_) 

Что дает:

# id event l_country l_grades l_school l_x l_y 
#1 1 23  <NA>  43 primary <NA> <NA> 
#2 2 49  <NA>  <NA>  <NA> <NA> <NA> 
#3 3 99  Japan  <NA>  <NA> 49 52 
#4 4 89  <NA>  56  <NA> <NA> <NA> 
2

В R кадр данных, каждая строка должна соответствовать человеку/предмету, каждый столбец должен быть переменной. Таким образом, в ваш набор данных выше, вы хотите что-то вроде

dd = data.frame(id = 1:4, 
       event =c(23, 49, 99, 89), 
       grades = c(43, NA, NA, 56), 
       school=c("primary", NA, NA, NA)) 

где NA недостающее значение.


Небольшое обновление следующий комментарий:

  1. Если каждая строка "похожа", то это предлагаемый подход. Это означает, что все стандартные алгоритмы и графики будут работать. Если у вас есть большое количество атрибутов, это зависит от того, что такое большое. В частности, это вызывает проблемы с памятью/скоростью? Если нет, не беспокойтесь. Если это так, вам действительно нужны все атрибуты?

  2. Для обработки данных в формате JSON см пакетов, таких как jsonlite

+0

да, (а) У меня есть большой количество атрибутов, но это все равно должно быть достойным подходом ?, (b) есть ли способ извлечь строку JSON, а затем ввести его как это собственный столбец в кадре данных? – dimebucker91

+0

@ dimebucker91 См. Обновление. – csgillespie

+0

@ dimebucker91 Похоже, мы начали редактирование примерно в одно и то же время! – csgillespie