搜索
查看: 4547|回复: 13

生信编程直播第12题:json格式数据的格式化

[复制链接]

634

主题

1182

帖子

4030

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4030
发表于 2017-4-18 09:05:53 | 显示全部楼层 |阅读模式
json数据大家统一用我给的测试数据,自己下载:http://biotrainee.com/jbrowse/JB ... encodeMetaData.json 范例如下:
[AppleScript] 纯文本查看 复制代码
{
   "types" : {
      "data set" : {
         "pluralLabel" : "data sets"
      }
   },
   "items" : [
      {
         "technique" : "ChIP-chip",
         "factor" : "BEAF-32",
         "target" : "Non TF Chromatin binding factor",
         "principal_investigator" : "White, K.",
         "Tracks" : [
            "fly/White_INSULATORS_WIG/BEAF32"
         ],
         "submission" : "21",
         "label" : "BEAF-32;Embryos 0-12 hr;ChIP-chip",
         "category" : "Other chromatin binding sites",
         "type" : "data set",
         "Developmental-Stage" : "Embryos 0-12 hr",
         "organism" : "D. melanogaster"
      },
      {
         "technique" : "ChIP-chip",
         "factor" : "CP190",
         "target" : "Non TF Chromatin binding factor",
         "principal_investigator" : "White, K.",
         "Tracks" : [
            "fly/White_INSULATORS_WIG/CP190"
         ],
         "submission" : "22",
         "label" : "CP190;Embryos 0-12 hr;ChIP-chip",
         "category" : "Other chromatin binding sites",
         "type" : "data set",
         "Developmental-Stage" : "Embryos 0-12 hr",
         "organism" : "D. melanogaster"
      },

因为帖子长度有限,我就只截取了一部分,请自己下载查看,如果是完整的json,可以用在线工具查看结构:http://json.parser.online.fr/

如果不懂json格式的,请自行搜索哈,现在TCGA在GDC的metadata信息,就是json格式的。

我们需要从这个json文件里面提取:technique factor target principal_investigator submission label category type Developmental-Stage organism key  这几列信息,当然,是可以用正则表达式做的。
完成之后应该是:http://biotrainee.com/jbrowse/JB ... dencodeMetaData.csv

我就不多做介绍了,主要难点在于理解json,本次作业,推荐大家用已有的包,正则表达式虽然可以做,但是太麻烦了~

给一个perl代码如下;
[Perl] 纯文本查看 复制代码
#!/usr/bin/env perl
use strict;
use warnings;
use autodie ':all';
use 5.10.0;

use JSON 2;

my $data = from_json( do { local $/; open my $f, '<', $ARGV[0]; scalar <$f> } );

my @fields = qw( technique factor target principal_investigator submission label category type Developmental-Stage organism key );

say join ',', map "\"$_\"", @fields;

for my $item ( @{$data->{items}} ) {
    $item->{key} = $item->{label};
    no warnings 'uninitialized';
    for my $track ( @{$item->{Tracks}} ) {
        $item->{label} = $track;
        say join ',', map "\"$_\"", @{$item}{@fields};
    }
}

希望有同学可以推陈出新,不要局限于我们的作业,可以自己下载TCGA的metadata信息,自己尝试提取,格式化。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x



上一篇:用 ASprofile 软件对 Cufflinks 预测的转录本的可变剪切事件进...
下一篇:刘祖洞《遗传学》学习笔记(持续更新中)
你这个问题很复杂,需要打赏,请点击 http://www.bio-info-trainee.com/donate 进行打赏,谢谢
回复

使用道具 举报

0

主题

4

帖子

89

积分

注册会员

Rank: 2

积分
89
QQ
发表于 2017-5-14 10:17:43 | 显示全部楼层
本帖最后由 xzmcxjb 于 2017-5-14 10:24 编辑

学了一个多月,终于能够照葫芦画瓢了。先贴代码:
[Python] 纯文本查看 复制代码
#!/user/bin/env.python
#coding = utf-8
import sys#导入sys模块
import json#导入json模块

args = sys.argv#提取参数
reload(sys)
sys.setdefaultencoding('utf-8')#重设置python的默认编码为utf8格式。

def get_keys(meta_data):#定义函数get_keys与参数meta_data
    all_dict = {}
    str_keys = {}
    list_keys = {}#初始化all_dict、str_keys、list_keys为空字典
    for item in meta_data:
        for key in item.keys():
            if type(item[key]) is list:#如果读值为列表就放在列表里
                list_keys[key] = 1
            else:
                str_keys[key] = 1#否则放在字符串里
            all_dict[key] = ''#初始化all_dict的值
    return all_dict, str_keys.keys(), list_keys.keys()#返回三个值

def main(args):
    meta_data = open(args[1]).read()#读入文件
    meta_data = json.loads(meta_data)['items']#将文件转换为字典
    all_dict, str_keys, list_keys = get_keys(meta_data)#将meta_data的值读入all_dict, str_keys, list_keys

    with open(args[2], 'w') as f_out:#建立输出文件
        f_out.write(','.join(all_dict.keys())+'\n')#连接all_dict的所有键,逗号分隔,末尾换行
        for v_item in meta_data:#循环遍历meta_data
            item_out = all_dict.copy()#深拷贝all_dict
            for k,v in v_item.items():#循环遍历v_item中的键和值
                item_out[k] = v#将值输出

            if 'Tracks' in v_item:#如果Tracks在v_item中
                for track in v_item['Tracks']:#循环遍历v_item中的‘Tracks’
                    item_out['Tracks'] = track#将track输出到item_out['Tracks']
                    f_out.write(','.join(item_out.values())+'\n')#将item_out的值连接,以逗号分隔,末尾换行
            else:
                f_out.write(','. join(item_out.values())+'\n')#如果v_item中没有Tracks,则直接将item_out的值连接,以逗号分隔,末尾换行

if __name__ == '__main__':#直接运行本程序
    main(args)
[/mw_shl_code]结果见附件。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 1 反对 0

使用道具 举报

29

主题

131

帖子

1208

积分

金牌会员

Rank: 6Rank: 6

积分
1208
发表于 2017-5-4 23:26:39 | 显示全部楼层
对于这个文件不熟悉,没找到key在哪。。

对于这类问题,我习惯的代码如下:

[Perl] 纯文本查看 复制代码
#!/usr/bin/perl -w
use strict;

local $/ = "}";
open my $fh, "modencodeMetaData.json" or die "Cannot open modencodeMetaData.json";
open my $fh_out, ">result.out" or die "Cannot write it";
readline $fh;
while(<$fh>){
	next unless ($_ =~ /{/);
	my $technique = $1 if ($_ =~ /"technique"\s+:\s+"(.*?)"/);
	my $factor = $1 if ($_ =~ /"factor"\s+:\s+"(.*?)"/);
	my $target = $1 if ($_ =~ /"target"\s+:\s+"(.*?)"/);
	my $principal_investigator = $1 if ($_ =~ /"principal_investigator"\s+:\s+"(.*?)"/);
	my $submission = $1 if ($_ =~ /"submission"\s+:\s+"(.*?)"/);
	my $label = $1 if ($_ =~ /"label"\s+:\s+"(.*?)"/);
	my $category = $1 if ($_ =~ /"category"\s+:\s+"(.*?)"/);
	my $type = $1 if ($_ =~ /"type"\s+:\s+"(.*?)"/);
	my $Developmental_Stage = $1 if ($_ =~ /"Developmental-Stage"\s+:\s+"(.*?)"/);
	my $organism = $1 if ($_ =~ /"organism"\s+:\s+"(.*?)"/);
	print $fh_out "$technique\t$factor\t$target\t$principal_investigator\t$submission\t$label\t$category\t$type\t$Developmental_Stage\t$organism\n";
}
close $fh;
close $fh_out;



#my $a = <$fh>;
#print $a;

回复 支持 反对

使用道具 举报

2

主题

34

帖子

773

积分

高级会员

Rank: 4

积分
773
发表于 2017-5-15 13:20:42 | 显示全部楼层
本帖最后由 x2yline 于 2017-5-15 13:22 编辑

077-x2yline

用re解析json格式, 并输出到xls文件中
代码如下
[Python] 纯文本查看 复制代码
# coding:utf-8
import re:
from collections import OrderedDict
def tcga_json(json_file, output_file): 
    with open(json_file, encoding='utf-8') as f:
        raw_txt = f.read()
        target_txt = raw_txt[raw_txt.find('[')+1:raw_txt.rfind(']')]
        all_data = OrderedDict()
        count_item = 0
        for item in target_txt.strip().split('}'):
            item = item.split('{')[-1]
            if item:
                count_item += 1
                for j, k in re.findall('"(.*?)" : "(.*?)",', item):
                    try:
                        all_data[j] = all_data[j] + [''] * (count_item-len(all_data[j])-1) + [k]
                    except:
                        all_data[j] = [''] * (count_item-1) + [k]
        for key in all_data.keys():
            if len(all_data[key]) < count_item:
                all_data[key] = all_data[key] + ['']*(count_item-len(all_data[key]))
    with open(output_file, 'w') as f:
        output = '\t'.join(all_data.keys())
        for i in range(count_item):
            output =  output+ '\n' + '\t'.join([all_data[key_i][i] for key_i in all_data.keys()])
        f.write(output)[/i][i]
if __name__ == '__main__':
    tcga_json('modencodeMetaData.json', 'output.xls')


回复 支持 反对

使用道具 举报

0

主题

16

帖子

145

积分

注册会员

Rank: 2

积分
145
发表于 2017-5-16 17:10:06 | 显示全部楼层
本帖最后由 azazelcc 于 2017-5-20 14:22 编辑

python有点太麻烦了,所以就捡起了已经快忘光的R

生信真的有必要学多种语言,python可能要很多行的,r只要几行。

[AppleScript] 纯文本查看 复制代码
library("rjson")
library("plyr")

json_data<- fromJSON(file = "modencodeMetaData.json")

json_data<- json_data$items

data_list<-lapply(json_data, as.data.frame, stringAsFactors=FALSE)

res<-rbind.fill(data_list)

index<-duplicated(res$submission)

res<-res[!index,]

write.csv(res,file = "abc.csv")


没有做数据去重,所以因为Tracks多了几行,正在研究。(fixed)

感谢版主的帮助,代码已经改正。
回复 支持 反对

使用道具 举报

64

主题

138

帖子

681

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
681
发表于 2017-5-19 22:10:07 | 显示全部楼层
azazelcc 发表于 2017-5-16 17:10
python有点太麻烦了,所以就捡起了已经快忘光的R

生信真的有必要学多种语言,python可能要很多行的,r只要 ...

同意,就是那个简单用哪个
回复 支持 反对

使用道具 举报

64

主题

138

帖子

681

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
681
发表于 2017-5-19 22:17:30 | 显示全部楼层
azazelcc 发表于 2017-5-16 17:10
python有点太麻烦了,所以就捡起了已经快忘光的R

生信真的有必要学多种语言,python可能要很多行的,r只要 ...

、duplicated函数,可以对数据框去重
回复 支持 反对

使用道具 举报

0

主题

16

帖子

145

积分

注册会员

Rank: 2

积分
145
发表于 2017-5-20 09:31:08 | 显示全部楼层
学习最快乐 发表于 2017-5-19 22:17
、duplicated函数,可以对数据框去重

十分感谢,我本来是打算重写as.dataframe里边加个判断,判断一下,如果多个元素就转换成一个独立的str
回复 支持 反对

使用道具 举报

0

主题

9

帖子

45

积分

新手上路

Rank: 1

积分
45
发表于 2017-6-6 18:36:02 | 显示全部楼层
还不知道怎么把for改成lapply,求指教
[AppleScript] 纯文本查看 复制代码
library("RJSONIO")
setwd("~/Downloads")
x<-fromJSON("modencodeMetaData.json")
col<-c("technique","factor","target","principal_investigator",
       "submission","label","category","type","Developmental-Stage","organism")
d<-c()
for(i in seq(1,length(x$items),1)) {
  item=as.character(x$items[][col])
  names(item)<-col
  item3<-unlist(item,use.names = F)
  d<-c(d,item3)
}
dMatrix=matrix(d,nrow=length(x$items),ncol=length(col),byrow = T)
colnames(dMatrix)<-col

回复 支持 反对

使用道具 举报

0

主题

9

帖子

45

积分

新手上路

Rank: 1

积分
45
发表于 2017-6-6 18:42:34 | 显示全部楼层
azazelcc 发表于 2017-5-16 17:10
python有点太麻烦了,所以就捡起了已经快忘光的R

生信真的有必要学多种语言,python可能要很多行的,r只要 ...

data_list<-lapply(json_data, as.data.frame, stringAsFactors=FALSE)
Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE,  :
  参数值意味着不同的行数: 1, 2, 4, 6, 17, 5, 3
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|生信技能树 ( 粤ICP备15016384号  

GMT+8, 2019-8-22 22:37 , Processed in 0.048197 second(s), 30 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.