首页 > 解决方案 > 将人类可读的连接表读取到 tibble

问题描述

我有一些人类可读的制表符分隔数据,格式如下:

Table_1
10      20      30
30      40      50
10      20      40
Table_2
20      30      40
10      50      60
30      20      10
30      10      40
Table_3
20      30      50
30      50      40

我想将表名保留为一列,如下所示:

Table_1 10      20      30
Table_1 30      40      50
Table_1 10      20      40
Table_2 20      30      40
Table_2 10      50      60
Table_2 30      20      10
Table_2 30      10      40
Table_3 20      30      50
Table_3 30      50      40

我可能可以用awkand解决这个问题sed,但我更喜欢使用这种tidyr方法。

标签: rtidyrtibble

解决方案


根据 'Table' 子字符串的出现创建一个分组列,使用first('grp') 分组的列中的观察值创建一个新列,删除第一个观察值 ( slice) 并转换type

library(dplyr)
library(stringr)
df1 %>%
     group_by(grp = cumsum(str_detect(V1, 'Table'))) %>% 
      mutate(Table = first(V1)) %>%
      slice(-1) %>%
      ungroup %>%
      type.convert(as.is = TRUE) %>%
      select(Table, everything(), -grp)

-输出

# A tibble: 9 x 4
  Table      V1    V2    V3
  <chr>   <int> <int> <int>
1 Table_1    10    20    30
2 Table_1    30    40    50
3 Table_1    10    20    40
4 Table_2    20    30    40
5 Table_2    10    50    60
6 Table_2    30    20    10
7 Table_2    30    10    40
8 Table_3    20    30    50
9 Table_3    30    50    40

数据

df1 <- read.table('file.txt', header = FALSE, fill = TRUE)
df1 <- structure(list(V1 = c("Table_1", "10", "30", "10", "Table_2", 
"20", "10", "30", "30", "Table_3", "20", "30"), V2 = c(NA, 20L, 
40L, 20L, NA, 30L, 50L, 20L, 10L, NA, 30L, 50L), V3 = c(NA, 30L, 
50L, 40L, NA, 40L, 60L, 10L, 40L, NA, 50L, 40L)), class = "data.frame", row.names = c(NA, 
-12L))

推荐阅读