【问题标题】:How can I import and re-export a text file without changing the spacing or columns?如何在不更改间距或列的情况下导入和重新导出文本文件?
【发布时间】:2019-01-16 20:28:25
【问题描述】:

我有一个从一些旧的专有软件生成的文件 (prf003.tre),我正在尝试在 R 中进行编辑。 它的结构如下:

0001  116.00 1BF 19.2     0.0             5500        0           
0001  216.00 1BF 19.2     0.0             5500        0           
0001  316.00 1BF 19.2     0.0             5500        0           
0001  416.00 1BF 19.2     0.0             5500        0           
0001  516.00 1BF 19.2     0.0             5500        0           
0001  616.00 1BF 19.2     0.0             5500        0           
0001  716.00 1BF 19.2     0.0             5500        0           

目标是能够导入文件,修改第2列的值来读取

prf003[, 2]

然后重新导出文件。

(每个单元格之间大约有 10-20 个空格,具体取决于哪一列。不幸的是,将其复制到 stackoverflow 中不会使其显示为这种方式,所以我将其粘贴为代码,希望没关系,对不起,我是新手。我需要以保持间距的完整性。)

我尝试导入 R,同时尝试 read.table 和 readLines。 read.table 不保留间距,但是我无法使用 readLines 修改第 2 列,因为它将它作为一列读取。有什么建议么?也许 read.table 中有一个我不知道的设置,但搜索并没有带来任何结果。

编辑:read.Table 还在我的第一列中删除了 0,有关如何保留“0001”的任何提示都会有所帮助。

【问题讨论】:

  • 源文件中的间距是什么样的?您是否要在列之间保留确切数量的空格?
  • 另外,使用read.table(data, colClasses = "character") 将防止前导零被丢弃。
  • @Mako212 间距如我粘贴的数据表所示-> col 1和col 2之间有2个空格,2和3之间有1个空格,3和4之间有5个空格第 4 列和第 5 列之间,第 5 列和第 6 列之间有 13 个空格,第 6 列和第 7 列之间有 8 个空格。是的

标签: r read.table


【解决方案1】:

假设我们有使用readLines 读入的字符向量L,如最后的注释所示。然后假设您希望第 2 列的替换在小数点后也有 2 位:

substr(L, 7, 12) <- sprintf("%6.2f", seq_along(L))
writeLines(L, stdout()) # replace stdout() with "myfile.dat", say

给予:

0001    1.00 1BF 19.2     0.0             5500        0
0001    2.00 1BF 19.2     0.0             5500        0
0001    3.00 1BF 19.2     0.0             5500        0
0001    4.00 1BF 19.2     0.0             5500        0
0001    5.00 1BF 19.2     0.0             5500        0
0001    6.00 1BF 19.2     0.0             5500        0
0001    7.00 1BF 19.2     0.0             5500        0

注意

Lines <- "0001  116.00 1BF 19.2     0.0             5500        0           
0001  216.00 1BF 19.2     0.0             5500        0           
0001  316.00 1BF 19.2     0.0             5500        0           
0001  416.00 1BF 19.2     0.0             5500        0           
0001  516.00 1BF 19.2     0.0             5500        0           
0001  616.00 1BF 19.2     0.0             5500        0           
0001  716.00 1BF 19.2     0.0             5500        0"
L <- trimws(readLines(textConnection(Lines)))

【讨论】:

  • 谢谢。这几乎可以工作,除了第 10 行的一些奇怪的原因,输出开始在第 2 列之前添加一个新列 "0001 1 10.00 1BF 19.2 0.0 5500 0" 请注意第 2 列中的值 1。它对所有后续行执行此操作。
  • 你是说输入不是问题中显示的形式吗?如果是这种情况,那么显然必须适当地更改代码。
  • 输入与问题中显示的形式相同,但包含的行数比示例所需的多得多。唯一的区别是第 10 行以后的第 2 列有 4 个数字而不是 3,这可能是导致错误 0001 1016.00 1BF 19.2 0.0 5500 0 的原因
  • 如果数字从第 6 列到第 12 列而不是从 7 到 12 列,则在 substr 中将 7 替换为 6,并在 sprintf 中使用 7 而不是 6,因为我们需要再填写一个字符位置。跨度>
【解决方案2】:

为了在列上使用 R 函数,我们需要先转换为数据框。这意味着我们将需要在最后重建源文件间距。

首先,我们将使用colClasses = 'character' 读取以保留前导零:

prf003 <- read.table(data, colClasses = "character")

prf003[, 2] <- seq.int(nrow(prf003))

现在,我们将为列间距定义一个向量,(注意,由于最后一列之后没有空格,我们需要在末尾添加一个空元素):

spacing <-  c("  ", " ","   ","     ", "             ", "        ","")

并使用mapplypaste0 将这些空格添加到每列的末尾(这适用于paste0(prf003[ ,1], spacing[[1]])paste0(prf003[ ,2], spacing[[2]]) 等:

formatted_prf <- mapply(paste0, prf003, spacing) 

然后我们可以使用write.table写回您的原始文件格式

write.table(formatted_prf, "new_prf.tre", sep = "", quote = FALSE, 
  col.names = FALSE, row.names = FALSE)

注意sep 必须为空,quote = FALSE 以免破坏我们的间距。

这是write.table的输出:

0001  1 1BF   19.2     0.0             5500        0
0001  2 1BF   19.2     0.0             5500        0
0001  3 1BF   19.2     0.0             5500        0
0001  4 1BF   19.2     0.0             5500        0
0001  5 1BF   19.2     0.0             5500        0
0001  6 1BF   19.2     0.0             5500        0
0001  7 1BF   19.2     0.0             5500        0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-09
    • 2020-10-11
    • 2021-01-02
    相关资源
    最近更新 更多