我有一个txt文件,其中包含以下数据:
1 message («random_choice»)[5];
2 reply («принято»)[2][3];
3 regulate («random_choice»)[5];
4 Early reg («for instance»)[2][3][4];
4xx: Success (загрузка):
6 OK («fine»)[2][3];
我想将其转换为数据框,由三列ID,消息,注释组成。 我也想删除方括号中末尾不必要的数字。 并且ID列中的某些值也包含字符串(通常为xx)。在这些情况下,列必须为空。 因此,所需的结果必须如下所示:
ID Message Comment
1 message random_choice
2 reply принято
3 regulate random_choice
4 Early reg for instance
Success загрузка
6 OK fine
我该怎么做?即使我尝试读取此txt文件,我也会收到奇怪的错误:
df <- read.table("data_received.txt", header = TRUE)
我得到的错误:
Error in read.table("data_received.txt", header = TRUE) :
more columns than column names
答案 0 :(得分:4)
您可以为此使用strcapture
。
伪造数据,您很可能会txt <- readLines("data_received.txt")
。 (由于我在Windows上的语言环境对那些字符串不友好,因此,假设它在您的系统上可以正常工作,我将用纯ascii代替。)
txt <- readLines(textConnection("1 message («random_choice»)[5];
# 2 reply («asdf»)[2][3];
# 3 regulate («random_choice»)[5];
# 4 Early reg («for instance»)[2][3][4];
# 4xx: Success (something):
# 6 OK («fine»)[2][3];"))
突破:
out <- strcapture("^(\\S+)\\s+([^(]+)\\s+\\((.*)\\).*$", txt,
proto = data.frame(ID=0L, Message="", Comment=""))
# Warning in fun(mat[, i]) : NAs introduced by coercion
out
# ID Message Comment
# 1 1 message «random_choice»
# 2 2 reply «asdf»
# 3 3 regulate «random_choice»
# 4 4 Early reg «for instance»
# 5 NA Success something
# 6 6 OK «fine»
proto=
参数指示生成什么类型的列。由于我设置了ID=0L
,因此假设它是整数,因此任何不转换为整数的东西都将变成NA
(满足您的第五行遗漏)。
对正则表达式的解释:
*
表示上一个字符(或字符类)为零或更多+
意味着一个或多个?
(未使用,但仍然有用)表示零或一。^
和$
分别表示字符串的开头和结尾(^
中的[..]
不同)(...)
是一个捕获组:未转义的括号内的所有内容均已存储,所有未丢弃的内容均被丢弃[...]
是一个字符组,任何字符都是一个匹配项;如果它是[^..]
,那么它将被倒置:除了列出的任何内容[[...]]
是一个字符类 ^(\\S+)
,以(^
)个或多个(+
)个非空格字符(\\S
)开始; \\s+
一个或多个空格字符(\\s
)(已舍弃); ([^(]+)
一个或多个不是左括号的字符; \\((.*)\\)$
一个文字左括号(\\(
),然后零个或多个任何内容(.*
),全部到达文字右括号(\\)
)和字符串结尾($
)的方式。应注意,\\s
和\\S
是非POSIX regex字符,通常建议将[^[:space:]]
用于\\S
(不带空格),并且[[:space:]]
的{{1}}。这些是等效的,但我最初使用代码高尔夫球。替换后,它看起来像
\\s
答案 1 :(得分:1)
我们可以使用 {unglue} 。在这里,我们看到您有两种模式,一种包含“«”和ID
,另一种则没有。 {unglue} 将使用第一个匹配的模式。任何{foo}
或{}
表达式都与正则表达式“。*?”匹配,并且data.frame是由放在方括号之间的名称构建的。
txt <- c(
"1 message («random_choice»)[5];", "2 reply («asdf»)[2][3];",
"3 regulate («random_choice»)[5];", "4 Early reg («for instance»)[2][3][4];",
"4xx: Success (something):", "6 OK («fine»)[2][3];")
library(unglue)
patterns <-
c("{id} {Message} («{Comment}»){}",
"{} {Message} ({Comment}){}")
unglue_data(txt, patterns)
#> id Message Comment
#> 1 1 message random_choice
#> 2 2 reply asdf
#> 3 3 regulate random_choice
#> 4 4 Early reg for instance
#> 5 <NA> Success something
#> 6 6 OK fine