R:解析和存储由空间分隔的分层结构化数据以及快速搜索和快速访问

桑奇特赛尼

我有一个包含多个字段的大型数据集,其值由空格分隔。然后,将这些字段组合在一起以形成一条记录,并且每条记录可以具有可变长度的子项(带有制表符)。

文件内容看起来像这样:

company Samsung
type private
based South Korea

    company Harman International
    type private
    based United States
    industry Electronics

        company JBL
        type subsidiary
        based United States
        industry Audio

company Amazaon
type public
based United States
industry Cloud computing, e-commerce, artificial intelligence, consumer electronics

我想在存储这些记录的同时保持层次结构,并选择进行快速搜索和访问每条记录的方式。

到目前为止,我想出了这种方法:

# reading file from the source
path <- "/path/to/file.txt"
content <- readLines(path, warn = F)


# replaces , with ; so it does not translate it as a separator in next step
content <- gsub(",", ";", content)

# creating list of fields and value
contentList <- read.csv(text=sub(" ", ",", content), header=FALSE)

# replacing ; with , to revert data in right format
contentList$V2 <- gsub(";", ",", contentList$V2)

经过以上步骤,contentList如下所示:

contentList输出

在下一步中,我考虑使用一个函数来创建具有以下规则的列表:

  1. 如果该字段没有任何内容,\t则将其添加到列表中(作为命名向量)
  2. 如果该字段具有一个或多个字段,\t使其成为先前记录的子列表(如命名矢量)

但是不知道如何在R中实现。

我应该如何实施呢?

还是有更好的方法来解决此问题,该问题可以快速执行搜索和访问值?

G.格洛腾迪克

使用末尾“注释”中的内容,计算每个公司行开头的空格,并使用gsubfn将其替换为给出L2的级别编号。然后修剪掉前导空格后,用冒号L3替换每行的第一个空格。该文件现在为dcf格式,因此请使用read.dcf读取它以得到L4。

现在生成一个lv变量,将级别号指定为数字,并为每一行生成顺序的数字ID。计算给定父代的父代ID,然后使用到目前为止已计算的内容构造一个数据框。树的整体根由0表示。从DF生成图的边列表e,并将其转换为igraph。从中生成简单路径,并创建具有列路径,公司,类型,基础和行业的数据帧DF2,以使每一行代表根以外的一个节点。

如果您愿意,可以将lv和parent添加到我们计算出的数据帧中,但由于您可能不需要它们而未添加。

下面的假设是每个缩进为4个空格。

对级别可以走多深没有限制。

我们可以使用数据框操作搜索DF2,以查找各种基于文本的查询,例如

subset(DF2, grepl("Samsung", paths))  # Samsung and its descendents

或者我们可以使用igraph函数对g进行图形查询,例如

max(length(get.diameter(g))) - 1   # max depth not counting root

或者我们可以使用data.tree函数进行查询

dt$height -  1  # max depth not counting root

代码如下。

library(gsubfn)

content <- readLines(textConnection(Lines))
L2 <- gsubfn("( *)company", ~ paste0("level ", nchar(x) / 4L + 1L, "\ncompany"), content)
L3 <- sub(" ", ":", trimws(readLines(textConnection(L2))))
L4 <- read.dcf(textConnection(L3))
lv <- as.numeric(L4[, 1])
id <- seq_along(lv)
company <- L4[, "company"]
parent <- sapply(id, function(i) c(tail(which(lv[1:i] < lv[i]), 1), 0)[1])  

DF <- data.frame(id = company[id], parent = c("0", company)[parent+1], 
  level = lv, L4[, -1], stringsAsFactors = FALSE)
e <- with(DF, cbind(parent, id))

现在我们有了边缘列表,我们可以创建一个igraph并使用该程序包对其进行处理。

library(igraph)

g <- graph_from_edgelist(e)

p <- all_simple_paths(g, "0")
paths <- sapply(p, function(x) paste(names(x), collapse = "/"))
DF2 <- data.frame(paths, L4[, -1], stringsAsFactors = FALSE)
DF2

提供一个path列,后跟每个节点的属性:

                               paths              company       type         based                                                                   industry
1                          0/Samsung              Samsung    private   South Korea                                                                       <NA>
2     0/Samsung/Harman International Harman International    private United States                                                                Electronics
3 0/Samsung/Harman International/JBL                  JBL subsidiary United States                                                                      Audio
4                          0/Amazaon              Amazaon     public United States Cloud computing, e-commerce, artificial intelligence, consumer electronics

我们可以这样绘制图形:

plot(g, layout = layout_as_tree(g))

(续图) 屏幕截图

数据树

我们还可以使用data.tree及其许多功能来处理此问题:

library(data.tree)
library(DiagrammeR)

dt <- FromDataFrameNetwork(DF)
print(dt, "type", "based", "industry")

给予:

                     levelName       type         based                                                                   industry
1 0                                                                                                                               
2  ¦--Samsung                     private   South Korea                                                                           
3  ¦   °--Harman International    private United States                                                                Electronics
4  ¦       °--JBL              subsidiary United States                                                                      Audio
5  °--Amazaon                      public United States Cloud computing, e-commerce, artificial intelligence, consumer electronics

我们可以如下绘制或转换数据树数据

plot(dt)  # plot in browser
ToListSimple(dt) # convert to nested list
ToListExplicit(dt) # similar but children in children component

注意

我们可以像这样重复创建内容:

Lines <- "
company Samsung
type private
based South Korea

    company Harman International
    type private
    based United States
    industry Electronics

        company JBL
        type subsidiary
        based United States
        industry Audio

company Amazaon
type public
based United States
industry Cloud computing, e-commerce, artificial intelligence, consumer electronics"

content <- readLines(textConnection(Lines))

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

解析混合结构化和非结构化数据

来自分类Dev

在SQLite中存储矩阵数据以在R中快速检索

来自分类常见问题

Pyspark分组和结构化数据

来自分类Dev

Cassandra和非结构化数据

来自分类Dev

PHP SVGGraph和结构化数据

来自分类Dev

Pyspark分组和结构化数据

来自分类Dev

C ++:具有快速搜索和较少内存需求的数据结构

来自分类Dev

我应该使用哪种数据结构进行快速删除/插入和最大(或最小)搜索?

来自分类Dev

哪种数据结构支持快速插入,删除和搜索

来自分类Dev

C ++:具有快速搜索和较少内存需求的数据结构

来自分类Dev

R:数据框的组织,结构化和子集化数据框

来自分类Dev

如何从结构化字符串或列表Python中访问和提取数据

来自分类Dev

快速访问和命名空间扩展:取消固定对象

来自分类Dev

文本文件的解析和结构化

来自分类Dev

解析半结构化json数据(Python / R)

来自分类Dev

如何快速存储和访问常用命令?

来自分类Dev

如何快速解析和存储json字典中的整数值?

来自分类Dev

如何快速解析和存储json字典中的整数值?

来自分类Dev

Knockoutjs映射和非结构化数据

来自分类Dev

Jekyll-数据文件和结构化YAML

来自分类Dev

Web服务(基本)和非结构化数据组合

来自分类Dev

Firestore规则,查询和结构化数据

来自分类Dev

Node.js和Redis结构化数据

来自分类Dev

REST API和GET与结构化数据

来自分类Dev

Knockoutjs映射和非结构化数据

来自分类Dev

列表的结构化和非结构化的区别

来自分类Dev

SSD和快速存储技术

来自分类Dev

如何解析结构化PDF以收集所有文本和框的元数据作为数据字典

来自分类Dev

解析和快速的关系查询

Related 相关文章

热门标签

归档