Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在R中扩展JSON列_Json_R_Csv - Fatal编程技术网

在R中扩展JSON列

在R中扩展JSON列,json,r,csv,Json,R,Csv,我正在从CSV文件中读取数据表。CSV中的某些元素采用JSON格式,因此其中一列包含JSON格式的数据,例如: user_id tv_sec action_info 1: 47074 1426791420 {"foo": {"bar":12345,"baz":309}, "type": "type1"} 2: 47074 1426791658 {"foo": '{"bar":23409,"baz":903}, "type

我正在从CSV文件中读取数据表。CSV中的某些元素采用JSON格式,因此其中一列包含JSON格式的数据,例如:

       user_id   tv_sec        action_info
  1:   47074     1426791420    {"foo": {"bar":12345,"baz":309}, "type": "type1"}
  2:   47074     1426791658    {"foo": '{"bar":23409,"baz":903}, "type": "type2"}
  3:   47074     1426791923    {"foo": {"bar":97241,"baz":218}, "type": "type3"} 
我想将action_info列展平,并将数据添加为列,如下所示:

       user_id   tv_sec        bar     baz    type
  1:   47074     1426791420    12345   309    type1
  2:   47074     1426791658    23409   903    type2
  3:   47074     1426791923    97241   218    type3
我不知道如何做到这一点。我在R(RJSONIO)中找到了一个将字符串转换为JSON的库,但我很难想出下一步该怎么做。当我尝试使用命令
userActions[,(fromJSON(action\u info))]
action\u info
列中的所有行转换为JSON时,我基本上得到了一个数据表,其中包含以某种方式累积的所有值,我并不完全清楚。例如,使用我得到的(非示例)数据运行:

                                                    V1
1: 2.188603e+12,2.187628e+12,2.186202e+12,1.164000e+03
2:                                               type1
Warning messages:
1: In if (is.na(encoding)) return(0L) :
  the condition has length > 1 and only the first element will be used
2: In if (is.na(i)) { :
  the condition has length > 1 and only the first element will be used
所以,我想弄明白:

  • 如何对列进行操作以将其从JSON转换为值(我认为我这样做是正确的,但我不确定)
  • 如何在当前或新数据表中获取值并从中创建列

  • 相当难看,但应该有效:

    library(dplyr)
    library(data.table)
    
    lapply(as.character(df$action_info), RJSONIO::fromJSON) %>% 
        lapply(function(e) list(bar=e$foo[1], baz=e$foo[2], type=e$type)) %>% 
        rbindlist() %>%
        cbind(df) %>% 
        select(-action_info)
    
    数据:

    工作原理:

    by=action\u info
    基本上确保我们只需从JSON中调用
    一次,每个unique
    action\u info
    (在您的情况下,每行一次);这是因为
    fromJSON
    对矢量化输入不起作用

    fromJSON(action\u info[1])
    action\u info
    转换为JSON(由于
    fromJSON
    不支持向量输入,因此
    [1]
    很可能有多行具有相同的
    action\u info

    unlist
    将嵌套的“foo:{bar…}”(do
    fromJSON(df$action\u info[1])
    unlist(fromJSON(df$action\u info[1])
    展开,以了解我的意思

    as.list
    将结果转换回一个列表,每个“列”有一个元素(
    data.table
    需要它来执行多重赋值)

    然后
    c('bar','baz','type'):=
    将输出重新分配给列


    请注意,我们没有按名称匹配,因此“bar”始终是JSON的第一部分,“baz”始终是第二部分,等等。如果您的
    action_info
    可以有一个
    {bar:…,baz:…}
    以及一个
    {baz:…,bar:}
    第二部分的
    baz
    将分配给
    bar
    列。如果你想变得更聪明并按名称分配,你必须想一些更聪明的事情(因为你可以做
    as.list(…)[c('foo.bar','foo.baz','type')]
    以确保元素在分配前的顺序正确)。

    你看到了错误,因为
    action\u info
    是一个
    因子
    而不是字符串。您可以在读取数据时使用
    stringsAsFactors=FALSE
    ,也可以将数据转换为字符
    as.character(df$action\u info)
    ,然后使用
    fromJSON
    。问题是它根本不是一个有效的JSON。这是你的准确数据吗?这不是我的准确数据。我已将JSON修复为有效;对于这个问题我深表歉意。不过我的数据中也有同样的问题,我也在那里解决了。现在我不再犯那个错误了。编辑问题。
    library(data.table)
    df <- data.table(structure(list(user_id = c(47074L, 47074L, 47074L), tv_sec = c(1426791420L, 
    1426791658L, 1426791923L), action_info = c("{\"foo\": {\"bar\":12345,\"baz\":309}, \"type\": \"type1\"}", 
    "{\"foo\": {\"bar\":23409,\"baz\":903}, \"type\": \"type2\"}", 
    "{\"foo\": {\"bar\":97241,\"baz\":218}, \"type\": \"type3\"}"
    )), .Names = c("user_id", "tv_sec", "action_info"), row.names = c(NA, 
    -3L), class = "data.frame"))
    
    df[, c('bar', 'baz', 'type'):=as.list(unlist(fromJSON(action_info[1]))),
       by=action_info]