r语言 - 将合约信息的列式表转换为行

  • 本文关键字:转换 信息 r语言 r reformat
  • 更新时间 :
  • 英文 :


我有一个大的合约信息表(几百个合约(,全部收集在一个表格的一列中。 每个合约占用 6 个连续行。 我已经能够添加另一列(CAT(,指示列中每一行的内容:公司,地址,CitySTZip,联系人,合同,标题。[使用 R]

添加第二列来表示列名后数据的可重现版本,数据如下所示:

textFile <- "col1|col2
XYZCo|Company
123 Main Street|Address
Yourtown, MA 12345|CityStZip
Joe Smith|Contact
20-234-56/3|Contract
Process for Work|Title
ZZTop Co|Company
123 Jefferson Street|Address
Chicago, IL 60636|CityStZip
Jane Doe|Contact
23-274-11/3|Contract
Yet Another One|Title"
data <- read.csv(text=textFile,header = TRUE,sep="|")
data

col1      col2
1                 XYZCo   Company
2       123 Main Street   Address
3    Yourtown, MA 12345 CityStZip
4             Joe Smith   Contact
5           20-234-56/3  Contract
6      Process for Work     Title
7              ZZTop Co   Company
8  123 Jefferson Street   Address
9     Chicago, IL 60636 CityStZip
10             Jane Doe   Contact
11          23-274-11/3  Contract
12      Yet Another One     Title

我想对所有数据进行重新排序,以便每个合约在数据表中占据一行,并将 CAT 值作为列标题。

根据下面发布的答案的评论,尝试使用for()循环重新格式化文件失败。

for(i in 1:nrow(data)){
for(j in 1:6){
# got stuck here... 
}
} 

所需的输出如下所示:

Company Address           CitySTZip            Contact     Contract      Title
XYZCo 123 Main Street   Yourtown, MA 12345   Joe Smith   20-234-56/3   Process for Work

发布原始答案后,我意识到数据可能与我的假设不同,因为原始帖子中的内容引用了原始数据中的第 1 列和第 2 列。如果数据如下所示,则有一个相对简单的答案,将dplyrtidyr::pivot_wider()相结合。

首先,我们将读取数据并打印生成的数据框,包括数据值和列名称的 2 列。

textFile <- "col1|col2
XYZCo|Company
123 Main Street|Address
Yourtown, MA 12345|CityStZip
Joe Smith|Contact
20-234-56/3|Contract
Process for Work|Title
ZZTop Co|Company
123 Jefferson Street|Address
Chicago, IL 60636|CityStZip
Jane Doe|Contact
23-274-11/3|Contract
Yet Another One|Title"
data <- read.csv(text = textFile,header = TRUE, sep="|")

数据框如下所示:

> data
col1      col2
1                 XYZCo   Company
2       123 Main Street   Address
3    Yourtown, MA 12345 CityStZip
4             Joe Smith   Contact
5           20-234-56/3  Contract
6      Process for Work     Title
7              ZZTop Co   Company
8  123 Jefferson Street   Address
9     Chicago, IL 60636 CityStZip
10             Jane Doe   Contact
11          23-274-11/3  Contract
12      Yet Another One     Title

为了将数据框透视为宽格式整洁数据,我们需要添加一个 ID 列以将一个观测值与其他观测值区分开来。为此,我们可以将dplyr::mutate()ceiling()函数一起使用。需要ceiling()函数,因为我们希望每 6 行输入数据的 ID 值是常量。当我们将seq_along()的结果除以 6 时,它会生成所需的向量。

添加 ID 列后,透视到宽格式相对简单。

library(dplyr)
library(tidyr)
data %>% mutate(id = ceiling(seq_along(col1)/6)) %>%
pivot_wider(.,id,names_from=col2,values_from=col1)

。和输出:

# A tibble: 2 x 7
id Company  Address          CityStZip       Contact  Contract   Title       
<dbl> <chr>    <chr>            <chr>           <chr>    <chr>      <chr>       
1     1 XYZCo    123 Main Street  Yourtown, MA 1… Joe Smi… 20-234-56… Process for…
2     2 ZZTop Co 123 Jefferson S… Chicago, IL 60… Jane Doe 23-274-11… Yet Another…

原始答案

这个问题的有趣挑战是,一个观察跨越 6 行数据,但不在固定的记录布局中,所以我们无法使用read.fwf()read.fortran()来读取文件。

相反,我们将使用readLines()将数据读入向量,然后将其写入临时文件,将每 6 行合并为单个输出记录。最后,我们将使用read.csv()读取重塑的数据。

原始帖子不清楚列名是否可以与原始数据文件中的其余数据区分开来,因此此解决方案假设我们需要从所需的结果数据框中解析它们。

textFile <- "XYZCo Company
123 Main Street Address
Yourtown, MA 12345 CityStZip
Joe Smith Contact
20-234-56/3 Contract
Process for Work Title
ZZTop Co Company
123 Jefferson Street Address
Chicago, IL 60636 CityStZip
Jane Doe Contact
23-274-11/3 Contract
Yet Another One Title"

首先,我们将数据读入带有readLines()的字符向量中。

dataVector <- readLines(textConnection(textFile))

接下来,我们从向量中去除列名数据。由于只有 6 列名称,所以我很懒,只是反复使用sub()。原始问题指示列名是在数据加载到 R 之后添加的,因此此代码可能是不必要的。

# clean column names from raw data 
dataVector <- sub("Company","",dataVector)
dataVector <- sub("Address","",dataVector)
dataVector <- sub("CityStZip","",dataVector)
dataVector <- sub("Contact","",dataVector)
dataVector <- sub("Contract","",dataVector)
dataVector <- sub("Title","",dataVector)

接下来,我们遍历向量,并将每 6 行合并为单个输出记录,使用管道|作为分隔符,因为数据在CityStZip字段中包含逗号。

# write to tempfile as pipe separated values
tmpFile <- "./data/tmpfile.csv"
counter <- 0
outLine <- NULL
for(i in 1:length(dataVector)){
counter <- counter + 1
if(counter == 1 ) outLine <- dataVector[i]
else outLine <- paste(outLine,dataVector[i],sep="|")
if(counter == 6) {
cat(outLine,file = "./data/tmpfile.csv",sep="n",append=TRUE)
counter <- 0
outLine <- NULL
}
}

最后,我们读取刚刚创建的文件,并指定sep = '|'作为列之间的分隔符。我们还使用col.names参数来设置列名。

colNames <- c("Company","Address","CityStZip","Contact","Contract","Title")
data <- read.csv("./data/tmpfile.csv",header = FALSE,sep = "|",
col.names = colNames)

。和输出:

> data
Company               Address           CityStZip    Contact     Contract
1    XYZCo       123 Main Street  Yourtown, MA 12345  Joe Smith  20-234-56/3 
2 ZZTop Co  123 Jefferson Street   Chicago, IL 60636   Jane Doe  23-274-11/3 
Title
1 Process for Work 
2  Yet Another One 

相关内容

  • 没有找到相关文章

最新更新