难以在R中导入具有多个不同分隔符的文本文件

时间:2018-05-21 21:14:39

标签: r

我无法弄清楚如何使用多个分隔符导入数据。以下是我的电脑自动保存到文本文件中的内容。问题是某些结果是用不同间距的分隔符打印的。一些分隔符是冒号(:),其他分隔符是长度不一致的多个空格。

每个字母(B:to Z :)代码为一些唯一变量。例如:

  • B:回复数量

  • C:秒数等

然而,下面的信息" Z:0.000",其中布局发生变化,是变量获得子集的时间。所以,

  • A:

  • 0:value1 value2 value3 value4

引用为:

  • A(0)= value1(e.x.第一次审判中的答复数量)

  • A(1)= value2(e.x.第二次审判中的答复数量)

  • A(2)= value3(e.x.第三次审判中的答复数量)

  • A(3)= value4(e.x.第四次审判中的答复数量)

这里有4" A"每个变量都可以携带唯一值。

文本文件示例:

Start Date: 05/20/18
End Date: 05/20/18
Subject: 1
Start Time: 16:23:11
End Time: 17:26:24
B:       7.000
C:   12000.000
D:    9500.000
E:       1.000
Q:     203.000
T:    1200.100
U:     218.000
W:       7.000
X:     347.000
Y:       0.000
Z:       0.000
A:
     0:        1.000        0.000        0.000        0.000
F:
     0:    11500.000     9500.000    13500.000     7500.000    15500.000
     5:     5500.000    17500.000

我尝试了一些方法,但由于多个分隔符问题而导致它们卡住了。让我们假设"数据"是文本文件。

# This is the closest - some of the values are still not separated properly

temp <- read.delim2(file = "data", quote = ":", sep = "",)

# This one separate the information mostly correctly for the top half only

temp <- read.delim2(file = "data", sep = ":")

我最终想要一个带有标签的数据帧(StartDate,A(0),B等)和另一列(05/20 / 201,1,7)中的值。

2 个答案:

答案 0 :(得分:1)

好消息是你的文件没有不同的分隔符。它是“Debian控制文件”格式。空白标记连续的线条。请参阅?read.dcf不幸的是,我无法弄清楚是否有办法解析.dcf,包括连续行的语义。但是,一旦数据在R中,你可以用library(tidyr)

清理它
x <- read.dcf("yoursourcefilename.txt")
y <– as.data.frame(x) # read.dcf reads in as matrix

z <- y %>% 
       separate("A", into = c("drop", "A0"), sep = "0:") %>% 
       separate("A0", into = c("drop", paste0("A0_val_", 1:4)), sep = "\\s{2,}") %>% 
       separate("F", into = c("drop", "F0"), sep = "0:") %>% 
       separate("F0", into = c("F0", "F5"), sep = "5:") %>% 
       separate("F0", into = c("drop", paste0("F0_val_", 1:5)), sep = "\\s{2,}") %>% 
       separate("F5", into = c("drop", paste0("F5_val_", 1:2)), sep = "\\s{2,}") %>%
       select(-drop) %>% t() %>% as.data.frame()

z$V1 <- trimws(z$V1) # clean whatever whitespace is left 

这将产生一个长数据帧:

 dim(z)
[1] 27  1

像这样:

  > z
                  V1
Start Date  05/20/18
End Date    05/20/18
Subject            1
Start Time  16:23:11
End Time    17:26:24
B              7.000
C          12000.000
D           9500.000
E              1.000
Q            203.000
T           1200.100
U            218.000
W              7.000
X            347.000
Y              0.000
Z              0.000
F5_val_1    5500.000
F5_val_2   17500.000
F0_val_1   11500.000
F0_val_2    9500.000
F0_val_3   13500.000
F0_val_4    7500.000
F0_val_5   15500.000
A0_val_1       1.000
A0_val_2       0.000
A0_val_3       0.000
A0_val_4       0.000

我不确定使用数据效率最高(不是整齐的格式),但这听起来像你想要的那样?

答案 1 :(得分:1)

希望这有帮助!

library(dplyr)
library(splitstackshape)

#read file
txt <- readLines("test.txt")

#Fix 'A:' rows
A_idx <- grep("A:", txt)
txt[A_idx] <- paste0(txt[A_idx], gsub("0:\\s+", "", txt[A_idx+1]))
txt <- txt[-(A_idx+1)]

#Fix 'F:' rows
F_idx <- grep("F:", txt)
txt[F_idx] <- paste0(txt[F_idx], paste(gsub("0:\\s+", "", txt[F_idx+1]), 
                                       gsub("5:\\s+", "", txt[F_idx+2])))
txt <- txt[-c(F_idx+1, F_idx+2)]

现在txt采用DCF格式,因此可以使用read.dcf

进行阅读
df <- data.frame(read.dcf(textConnection(txt)), stringsAsFactors = F) %>%
  cSplit("A", " ") %>%
  cSplit("F", " ")

输出为:

df

   Start.Date End.Date Subject Start.Time End.Time     B         C        D     E       Q        T
1:   05/20/18 05/20/18       1   16:23:11 17:26:24 7.000 12000.000 9500.000 1.000 203.000 1200.100
         U     W       X     Y     Z A_1 A_2 A_3 A_4   F_1  F_2   F_3  F_4   F_5  F_6   F_7
1: 218.000 7.000 347.000 0.000 0.000   1   0   0   0 11500 9500 13500 7500 15500 5500 17500

示例数据: test.txt包含

Start Date: 05/20/18
End Date: 05/20/18
Subject: 1
Start Time: 16:23:11
End Time: 17:26:24
B:       7.000
C:   12000.000
D:    9500.000
E:       1.000
Q:     203.000
T:    1200.100
U:     218.000
W:       7.000
X:     347.000
Y:       0.000
Z:       0.000
A:
  0:        1.000        0.000        0.000        0.000
F:
  0:    11500.000     9500.000    13500.000     7500.000    15500.000
  5:     5500.000    17500.000

Start Date: 05/20/18
End Date: 05/20/18
... another block of data


修改:如果您想要列A&amp; F从0开始的索引

#read DCF data (i.e 'txt') using read.dcf
df <- data.frame(read.dcf(textConnection(txt)), stringsAsFactors = F)

#convert column A into wide format by splitting it into multiple columns
A_df <- data.frame(do.call(rbind, strsplit(as.character(df$A),'\\s+')), stringsAsFactors = F)
colnames(A_df) <- paste("A", sequence(ncol(A_df))-1, sep = "_")

#convert column F into wide format by splitting it into multiple columns
F_df <- data.frame(do.call(rbind, strsplit(as.character(df$F),'\\s+')), stringsAsFactors = F)
colnames(F_df) <- paste("F", sequence(ncol(F_df))-1, sep = "_")

#final data
final_df <- cbind(df[, !names(df) %in% c("A", "F")], A_df, F_df)

给出了

final_df    
#  Start.Date End.Date Subject Start.Time End.Time     B         C        D     E       Q        T       U
#1   05/20/18 05/20/18       1   16:23:11 17:26:24 7.000 12000.000 9500.000 1.000 203.000 1200.100 218.000
#      W       X     Y     Z   A_0   A_1   A_2   A_3       F_0      F_1       F_2      F_3       F_4
#1 7.000 347.000 0.000 0.000 1.000 0.000 0.000 0.000 11500.000 9500.000 13500.000 7500.000 15500.000
#       F_5       F_6
#1 5500.000 17500.000