Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.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 将不规则文本拆分为表格_R - Fatal编程技术网

R 将不规则文本拆分为表格

R 将不规则文本拆分为表格,r,R,我的文本表如下所示: in.data <- rbind( c("ColA KB Col C The ColE (2.0)"), c("abc def ghijklm n opqrst"), c("uv wx y zzzzzz aa bcd"), c("ab cd gh jklmn") ) wanted.result <- rbind( c("abc", "def", "ghijklm"

我的文本表如下所示:

in.data <- rbind(
c("ColA KB      Col C    The ColE (2.0)"),
c("abc  def     ghijklm  n    opqrst"), 
c("uv   wx y    zzzzzz   aa   bcd"),
c("ab   cd               gh   jklmn")
)
wanted.result <- rbind(
    c("abc", "def", "ghijklm", "n", "opqrst"), 
    c("uv", "wx  y", "zzzzzz", "aa", "bcd"),
    c("ab", "cd", NA, "gh", "jklmn")
)
colnames(wanted.result) <- c("ColA", "KB", "Col C", "The", "ColE (2.0)")
我需要这样:

in.data <- rbind(
c("ColA KB      Col C    The ColE (2.0)"),
c("abc  def     ghijklm  n    opqrst"), 
c("uv   wx y    zzzzzz   aa   bcd"),
c("ab   cd               gh   jklmn")
)
wanted.result <- rbind(
    c("abc", "def", "ghijklm", "n", "opqrst"), 
    c("uv", "wx  y", "zzzzzz", "aa", "bcd"),
    c("ab", "cd", NA, "gh", "jklmn")
)
colnames(wanted.result) <- c("ColA", "KB", "Col C", "The", "ColE (2.0)")
使这一点变得复杂的是,垂直分隔符位置可以基于列名和列内容

以下是一个丑陋的尝试:

library(stringr)
spaces.1 <- unique(unlist(str_locate_all(in.data[1,], " ")))
spaces.2 <- unique(unlist(str_locate_all(in.data[2,], " ")))
spaces.3 <- unique(unlist(str_locate_all(in.data[3,], " ")))
spaces.4 <- unique(unlist(str_locate_all(in.data[4,], " ")))
spaces.12 <- spaces.1[spaces.1%in%spaces.2]
spaces.123 <- spaces.12[spaces.12%in%spaces.3]
spaces.1234 <- spaces.123[spaces.123%in%spaces.4]
for (i in length(spaces.1234):2) {
    if (spaces.1234[i]-spaces.1234[i-1]==1) spaces.1234[i] <- NA_integer_
}
delimiters <- na.omit(spaces.1234)
library(data.table)
in.data.table <- data.table(in.data)
in.data.table[, col.1:=substr(V1, start=1, stop=delimiters[1])]
in.data.table[, col.2:=substr(V1, start=delimiters[1], stop=delimiters[2])]
in.data.table[, col.3:=substr(V1, start=delimiters[2], stop=delimiters[3])]
in.data.table[, col.4:=substr(V1, start=delimiters[3], stop=delimiters[4])]
in.data.table[, col.5:=substr(V1, start=delimiters[4], stop=37)]
setnames(in.data.table, as.character(in.data.table[1, ]))
wanted.result.2 <- in.data.table[2:4, 2:6, with=FALSE]
但我需要这样做数千次,并且使用不同数量的列和行

有没有更好的方法可以做到这一点,它也适用于任意数量的行

更新:澄清一下,问题是根据标题和行中空格的位置来查找宽度。抱歉,我不太清楚。

在使用gregexpr调用计算列宽后,使用read.fwf查找定义列名的内容:

txt <- paste(c(in.data),collapse="\n")
widths <- diff(c(gregexpr("Col", in.data[1])[[1]], nchar(in.data[1])+1))
out <- read.fwf(textConnection(txt), widths=widths, skip=1)
names(out) <- unlist(read.fwf(textConnection(txt), widths=widths, n=1))
out

#  ColA  ColB     Col C     ColD  ColE (2.0)
#1 abc   def      ghijklm   n         opqrst
#2 uv    wx  y    zzzzzz    aa           bcd
#3 ab    cd                 gh         jklmn
使用gregexpr调用计算列宽后使用read.fwf查找定义列名的内容:

txt <- paste(c(in.data),collapse="\n")
widths <- diff(c(gregexpr("Col", in.data[1])[[1]], nchar(in.data[1])+1))
out <- read.fwf(textConnection(txt), widths=widths, skip=1)
names(out) <- unlist(read.fwf(textConnection(txt), widths=widths, n=1))
out

#  ColA  ColB     Col C     ColD  ColE (2.0)
#1 abc   def      ghijklm   n         opqrst
#2 uv    wx  y    zzzzzz    aa           bcd
#3 ab    cd                 gh         jklmn

我们假设所有行中包含空格的任何列都会分隔字段,并且我们假设最后一个字段的宽度为10或更小。如果需要,请更改此数字。没有使用任何软件包

w <- diff(Reduce(intersect, gregexpr(" ", paste("", in.data))))
w <- c(w, 10)
X <- read.fwf(textConnection(in.data), w, skip = 1, as.is = TRUE)
names(X) <- trimws(read.fwf(textConnection(in.data), w, n = 1, as.is = TRUE))
X <- X[names(X) != "NA"]
X[] <- lapply(X, trimws)
注意:我们在上面的测试运行中将其用作输入:

in.data <-
structure(c("ColA ColB    Col C    ColD ColE (2.0)", "abc  def     ghijklm  n    opqrst", 
"uv   wx  y   zzzzzz   aa   bcd", "ab   cd               gh   jklmn"
), .Dim = c(4L, 1L))

我们假设所有行中包含空格的任何列都会分隔字段,并且我们假设最后一个字段的宽度为10或更小。如果需要,请更改此数字。没有使用任何软件包

w <- diff(Reduce(intersect, gregexpr(" ", paste("", in.data))))
w <- c(w, 10)
X <- read.fwf(textConnection(in.data), w, skip = 1, as.is = TRUE)
names(X) <- trimws(read.fwf(textConnection(in.data), w, n = 1, as.is = TRUE))
X <- X[names(X) != "NA"]
X[] <- lapply(X, trimws)
注意:我们在上面的测试运行中将其用作输入:

in.data <-
structure(c("ColA ColB    Col C    ColD ColE (2.0)", "abc  def     ghijklm  n    opqrst", 
"uv   wx  y   zzzzzz   aa   bcd", "ab   cd               gh   jklmn"
), .Dim = c(4L, 1L))

这个过程需要一个规则来确定何时以及填写多少NA值。这本质上不是一个固定宽度的文本文件吗e、 g.-?read.fwf应该能够处理它。我认为read.fwf需要宽度,这在我的数据中是事先不知道的。这个过程需要一个规则来确定何时以及填写多少NA值。这本质上不是一个固定宽度的文本文件吗?-e、 g.-?read.fwf应该能够处理它。我认为read.fwf需要宽度,这在我的数据中是事先不知道的。对不起,我应该提到的是,并非所有列名都以col开头。我将在示例中对此进行更改。@Chris-如果没有明确的规则来定义列,您必须手动获取宽度。没有一个程序可以读心术。对不起,我应该提到的是,并非所有列名都以col开头。我将在示例中对此进行更改。@Chris-好吧,如果没有关于如何定义列的明确规则,您将不得不手动获取宽度。没有一个程序能读心术。