【问题标题】:Difficulty importing text file with multiple different delimiters in R难以在 R 中导入具有多个不同分隔符的文本文件
【发布时间】:2018-05-21 21:14:39
【问题描述】:

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

每个字母 (B: 到 Z:) 编码一些唯一变量。例如:

  • B:响应数

  • C:秒数等

但是,“Z:0.000”下方的信息,即布局发生变化的地方,是变量获取子集的时间。所以,

  • 答:

  • 0: value1 value2 value3 value4

被引用为:

  • A(0) = value1(例如第一次试验中的响应数)

  • A(1) = value2(例如第二次试验中的响应数)

  • A(2) = value3(例如第三次试验中的响应数)

  • A(3) = value4(例如第四次试验中的响应数)

这里有 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/2018, 1, 7)。

【问题讨论】:

  • 示例中的空格和换行符实际上是否在您要解析的文本文件中?这是一个有用的示例,可以很容易地查看格式,但是您能否也粘贴几行原始文本文件,我们可以用来测试处理数据的方法?
  • 该示例是在我的文本文件中找到的实际格式(所以是的 - 空格和换行符的显示与文件中的完全相同)。文件的下半部分似乎将其组织在与每列右侧对齐的列中。

标签: r


【解决方案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


编辑:如果您希望列 AF 的索引从 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

【讨论】:

    【解决方案2】:

    好消息是您的文件没有不同的分隔符。它是“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
    

    我不确定这是处理数据最有效的方式(不是整齐的格式),但听起来这就是您想要的?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-03
      • 1970-01-01
      • 1970-01-01
      • 2013-06-03
      • 2013-08-13
      相关资源
      最近更新 更多