通过为每个属性

时间:2016-09-18 11:22:17

标签: r json dataframe attributes

我有一个基于事件的数据集,每个事件都有JSON格式的属性,例如,数据的简化版本:

 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))

无需手动输入

第二次/第三次更新

我写过这个似乎有效,所以我想我会分享,如果有更简单的方法,请告诉我:

    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 个答案:

答案 0 :(得分: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. 如果每行是&#34;类似&#34;那么这是建议的方法。这意味着所有标准算法和图表都可以正常工作。如果你有大量的属性,那么它取决于什么是大的。具体来说,它会导致内存/速度问题吗?如果没有,请不要担心。如果是这样,你真的需要所有的属性吗?

  2. 有关处理json数据的信息,请参阅jsonlite

  3. 等软件包

答案 1 :(得分:2)

你可以尝试:

Group      Count
Jan-16     2
Feb-16     1
Mar-16     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_)