在R中扩展JSON列
我正在从CSV文件中读取数据表。CSV中的某些元素采用JSON格式,因此其中一列包含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
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
所以,我想弄明白:
相当难看,但应该有效:
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中调用一次,每个uniqueaction\u info
(在您的情况下,每行一次);这是因为fromJSON
对矢量化输入不起作用
fromJSON(action\u info[1])
将action\u info
转换为JSON(由于fromJSON
不支持向量输入,因此[1]
很可能有多行具有相同的action\u info
)
unlist
将嵌套的“foo:{bar…}”(dofromJSON(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]