2016-09-18 36 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中單獨有一個「屬性」表,並加入事件ID以獲取屬性及其值。我想知道在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)) 

,而無需手動輸入的方式,

第二/第三次更新

我已經WRI 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