2016-12-04 1 views
0

は、次のような構造を持つ巨大なテキストファイルをインポートしようとしています:これは、EXAMPLE.SQLとして保存された例です。Rでは、データを分割するテキストファイルからデータフレームを作成するにはどうすればよいですか? RIで

Curve Name: 
    Curve A 
Curve Values: 
    index Variable 1 Variable 2 
        [°C]   [%] 
    0    30   100 
    1    40   95 
    2    50   90 
Curve Color: 
    Blue 

Curve Name: 
    Curve B 
Curve Values: 
    index Variable 1 Variable 2 
        [°C]   [%] 
    0    30   100 
    1    40   90 
    2    50   80 
Curve Color: 
    Green 

これまでのところ、私は名前や色

file.text <- readLines("example.txt") 

curve.names <- trimws(file.text[which(regexpr('Curve Name:', file.text) > 0) + 1]) 
curve.colors <- trimws(file.text[which(regexpr('Curve Color:', file.text) > 0) + 1]) 

を抽出することができます次の構造体では、curve.nameを因子として、その他の値を数値としてデータフレームを作成するにはどうすればよいですか?

curve.name index variable.1 variable.2 
    Curve A 0    30   100 
    Curve A 1    40   95 
    Curve A 2    50   90 
    Curve B 0    30   100 
    Curve B 1    40   90 
    Curve B 2    50   80   

答えて

1

を一般grepの多くを:だから、それが与えるCurve Values:

を言う場所探し。グループエントリへの道を見つける、空白行の累積合計のように、同様に便利なことができます:

l <- readLines(textConnection('Curve Name: 
    Curve A 
Curve Values: 
    index Variable 1 Variable 2 
        [°C]   [%] 
    0    30   100 
    1    40   95 
    2    50   90 
Curve Color: 
    Blue 

Curve Name: 
    Curve B 
Curve Values: 
    index Variable 1 Variable 2 
        [°C]   [%] 
    0    30   100 
    1    40   90 
    2    50   80 
Curve Color: 
    Green ')) 

do.call(rbind, 
     lapply(split(trimws(l), cumsum(l == '')), function(x){ 
      data.frame(
       curve = x[grep('Curve Name:', x) + 1], 
       read.table(text = paste(x[(grep('index', x) + 2):(grep('Curve Color:', x) - 1)], 
             collapse = '\n'), 
          col.names = c('index', 'variable.1', 'varible.2')))})) 
##  curve index variable.1 varible.2 
## 0.1 Curve A  0   30  100 
## 0.2 Curve A  1   40  95 
## 0.3 Curve A  2   50  90 
## 1.1 Curve B  0   30  100 
## 1.2 Curve B  1   40  90 
## 1.3 Curve B  2   50  80 
+0

私はすべての答えをアップにしました。しかし、これは、追加パッケージなしで可変長カーブを処理するため選択されました。 「Curve Values:」という行の累計は、私が持っていた問題のために働いていました。 – Agriculturist

3

すべてのファイルは、上記から正確なフォーマットを持っていると仮定すると:

txt <- readLines("example.txt") 
curve_name <- rep(trimws(txt[c(2,13)]), each=3) 
curve_color <- rep(trimws(txt[c(10,21)]), each=3) 
val <- read.table(text=paste(txt[c(6:8, 17:19)], collapse = "\n")) 
colnames(val) <- c("index", "var1", "var2") 
cbind(curve_name, curve_color, val) 

形式は正確に上記のいずれでもない場合は、ヘッダーのを経由してラインインデックスを把握しようとすることができます。

curve_name curve_color index var1 var2 
1 Curve A  Blue  0 30 100 
2 Curve B  Blue  1 40 95 
3 Curve A  Blue  2 50 90 
4 Curve B  Green  0 30 100 
5 Curve A  Green  1 40 90 
6 Curve B  Green  2 50 80 
2

Curve Colorの前にスペースを削除Lにラインを読みます。 (実際のファイルにCurve Colorの前に空白がない場合、スペースを削除する必要はありませんが、質問にはCurve Colorの前に空白があります)。variables data.frameを作成する数字で始まる行を再度読み込みます。次にread.dcfを使用してrestを読んで、cbindを使用して2つをまとめてください。

我々は、我々は(空白文字で始まる)の数値テーブルの[, -2]

  • 行だけが数字で始まる使っrestからそれを省略することができるように

    1. 曲線値が第二来ることを想定しています。
    2. 各数値レコードには、3つの列があり、その列の名前はその質問に示されています。行はインデックス番号0で始まり、同じレコード内の後続の行には0 indexという番号もありません。 (各数値表の行数に制限はなく、異なるレコードの行数が異なる場合があります)。

    パッケージは使用されていません。

    L <- sub("^ *Curve Color", "Curve Color", readLines("example.txt")) 
    variables <- read.table(text = grep("^\\d", trimws(L), value = TRUE), 
    col.names = c("index", "variable.1", "variable.2")) 
    rest <- trimws(read.dcf(textConnection(L))[, -2]) 
    cbind(rest[cumsum(variables$index == 0), ], variables) 
    

    与える:予測可能なフォーマットを想定

    Curve Name Curve Color index variable.1 variable.2 
    1 Curve A  Blue  0   30  100 
    2 Curve A  Blue  1   40   95 
    3 Curve A  Blue  2   50   90 
    4 Curve B  Green  0   30  100 
    5 Curve B  Green  1   40   90 
    6 Curve B  Green  2   50   80 
    
  • +0

    異なるレコードが数値表の異なる行数を表す可能性があるポスターによるコメントに基づいて、これを可能にするようにコードを修正しました。また、いくつかの単純化のため、コードは以前よりも長くなりません。 –

    3

    わずかに異なるアプローチ。私たちはそれぞれの「記録」を得て、顕著な要素を抽出し、すべてを一緒に結びつけます。

    library(purrr) 
    library(stringi) 
    
    starts <- which(grepl("Curve Name:", lines)) # find the start of each record 
    ends <- which(grepl("Curve Color:", lines))+1 # find the end of each record 
    
    map2_df(starts, ends, function(start, end) { 
    
        rec <- paste0(lines[start:(end)], collapse="\n") # extract the record 
    
        # regex extract each set of values 
        stri_match_first_regex(rec, c("Curve Name:[[:space:]]+([[:alnum:][:blank:]]+)", 
               "Curve Values:[[:space:]]+([[:print:][:space:]]+)Curve", 
               "Curve Color:[[:space:]]+([[:alnum:][:blank:]]+)"))[,2] %>% 
        trimws() -> found 
    
        df <- read.table(text=found[2], skip=2, col.names=c("index", "variable.1", "variable.2")) 
        df$curve.name <- found[1] 
        df$color <- found[3] 
        df 
    
    }) 
    ## index variable.1 variable.2 curve.name color 
    ## 1  0   30  100 Curve A Blue 
    ## 2  1   40   95 Curve A Blue 
    ## 3  2   50   90 Curve A Blue 
    ## 4  0   30  100 Curve B Green 
    ## 5  1   40   90 Curve B Green 
    ## 6  2   50   80 Curve B Green 
    
    +0

    良い解決策。 @hrbrmstrなぜ 'stringw :: stri_trim_both'より' trimws'を使いますか? – Rentrop

    +1

    私は23:30EST :-)で簡潔に入力することにそれを責める – hrbrmstr

    関連する問題