2017-04-04 313 views
0

数据我已经是这样的:如何将此非结构化数据转换为结构化?

data <- c("24-March-2017  text1       874874455221112    Text text text10", 
    "25-March-2017  text2       54654656TEXT     Text text 11", 
    "24-March-2017  text3       874874455221112    Text text text 12", 
    "25-March-2017     text4       54654656TEXT     Text text 13", 
    "26-March-2017  text3    54654TEXT Text text text 14", 
    "27-March-2017    text5      6546TEXT Text text text 15", 
    "28-March-2017  text6       546476876586TExt Text text text 16", 
    "29-March-2017     text7  23453453TEXT  Text text 17") 

enter image description here

我想这个数据转换成基于每列之间的空间结构形式。前三行看起来像我希望数据看起来像。最终的结果需要看起来像:

enter image description here

基本上是:

  1. 第一列(日期)开始于零(无需更换)
  2. 第二列必须在位置开始20
  3. 第三列开始于位置50
  4. 最后一列开始于80
+0

'read.table(text = data,fill = TRUE,header = FALSE)'给你一个很好的R数据集,可以作为转换为新格式的干净基础。 – thelatemail

+0

为什么不把它保存为.csv,然后使用LibreOffice Calc加载它?它可以选择加载由空格分隔的文本文件(以及其他字符),也可以选择合并分隔符。稍后,您可以使用函数* concatenate *合并最后一列。 – Rodrigo

回答

3

这是根据各地提供的数据,并假定:

  • 有四列
  • 前三个都在其中没有空白和空白
  • 分离的最后一列可以包含空格

,拿出匹配的子串,rbindş他们进入一个矩阵,删除全局匹配,转换为data.frame,然后通过sprintf获得固定宽度输出。

data %>% 
    regmatches(regexec("^(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(.*?)$", .)) %>% 
    do.call("rbind", .) %>% 
    .[, -1] %>% 
    as.data.frame(stringsAsFactors = FALSE) %>% 
    c(list("%-20s%-30s%-30s%s"), .) %>% 
    do.call("sprintf", .) 

# [1] "24-March-2017  text1       874874455221112    Text text text10" 
# [2] "25-March-2017  text2       54654656TEXT     Text text 11"  
# [3] "24-March-2017  text3       874874455221112    Text text text 12" 
# [4] "25-March-2017  text4       54654656TEXT     Text text 13"  
# [5] "26-March-2017  text3       54654TEXT      Text text text 14" 
# [6] "27-March-2017  text5       6546TEXT      Text text text 15" 
# [7] "28-March-2017  text6       546476876586TExt    Text text text 16" 
# [8] "29-March-2017  text7       23453453TEXT     Text text 17" 
+0

很棒的答案。我想申请其他表格。 (1)第一列没有空格(2)第二列有1-5个空格(所有单个空格)(3)第三列和第四列有1个空格到3个单个空格(4)第5列中没有空格,最后(5)与上面相同的第6列包含多个空格。 – Curious

+0

列间距如何? –

+0

第一列从零开始,第二列在20,第三列在50,第四列在80,第五列在120,最后一列在180. – Curious

3
do.call('rbind', lapply(df, function(x) { # loop through vector df 
    x <- strsplit(x, "\ ")[[1]]    # split string by spaces 
    x <- x[which(unlist(lapply(x, nchar)) > 0)] # remove zero length strings 
    x <- c(x[1:3], paste(x[4:length(x)], collapse = " ")) # collapse all elements from 4 to end 
    return(x) # return formatted vector 
})) 

#     [,1] [,2]    [,3]     [,4]    
# [1,] "24-March-2017" "text1" "874874455221112" "Text text text10" 
# [2,] "25-March-2017" "text2" "54654656TEXT"  "Text text 11"  
# [3,] "24-March-2017" "text3" "874874455221112" "Text text text 12" 
# [4,] "25-March-2017" "text4" "54654656TEXT"  "Text text 13"  
# [5,] "26-March-2017" "text3" "54654TEXT"  "Text text text 14" 
# [6,] "27-March-2017" "text5" "6546TEXT"   "Text text text 15" 
# [7,] "28-March-2017" "text6" "546476876586TExt" "Text text text 16" 
# [8,] "29-March-2017" "text7" "23453453TEXT"  "Text text 17" 

基于@thelatemail评论

df <- read.table(text=df,fill=TRUE,header=FALSE) 
df[, 4] <- apply(df[, 4:ncol(df)], 1, function(x) { 
    paste(x[ ! is.na(x) ], collapse = ' ') }) 
df <- df[, 1:4] 
df 
#    V1 V2    V3    V4 
# 1 24-March-2017 text1 874874455221112 Text text text10 
# 2 25-March-2017 text2  54654656TEXT  Text text 11 
# 3 24-March-2017 text3 874874455221112 Text text text 12 
# 4 25-March-2017 text4  54654656TEXT  Text text 13 
# 5 26-March-2017 text3  54654TEXT Text text text 14 
# 6 27-March-2017 text5   6546TEXT Text text text 15 
# 7 28-March-2017 text6 546476876586TExt Text text text 16 
# 8 29-March-2017 text7  23453453TEXT  Text text 17 

数据:

df <- c("24-March-2017  text1       874874455221112    Text text text10", 
      "25-March-2017  text2       54654656TEXT     Text text 11", 
      "24-March-2017  text3       874874455221112    Text text text 12", 
      "25-March-2017     text4       54654656TEXT     Text text 13", 
      "26-March-2017  text3    54654TEXT Text text text 14", 
      "27-March-2017    text5      6546TEXT Text text text 15", 
      "28-March-2017  text6       546476876586TExt Text text text 16", 
      "29-March-2017     text7  23453453TEXT  Text text 17")