0

次のようなデータがあります。

   duration                       obs   another
 1 1.801760     ID: 10 DAY: 6/10/13 S    orange
 2 1.868500     ID: 10 DAY: 6/10/13 S     green
 3 0.233562     ID: 10 DAY: 6/10/13 S    yellow
 4 5.538760       ID:96 DAY: 6/8/13 T    yellow
 5 3.436700       ID:96 DAY: 6/8/13 T      blue
 6 0.533856       ID:96 DAY: 6/8/13 T      pink
 7 2.302250       ID:96 DAY: 6/8/13 T    orange
 8 2.779420       ID:96 DAY: 6/8/13 T     green

実際には私のデータには多くの変数がありますが、3 つの変数だけを含めました。私の問題は、見苦しい「obs」変数を扱うことです。これらのデータは、使用しているソフトウェアに一貫性のない方法でこの情報を入力した別の個人から受け取りました。

「obs」には次の 3 つの情報が含まれます: - ID (ID: 10、ID:96 など) - 日付 (M/D/Y) - 識別子 (S または T)

この情報を分割し、ID 番号 (10 または 96)、日付 (例: 6/8/13)、および識別子 (S または T) を抽出します。

これを行うために、strsplit を使用して次のことを試しました。

temp<-strsplit(as.character(df$obs), " ")
mat<-matrix(unlist(temp), ncol=5, byrow=TRUE)

私はこれが私の実際のデータのように機能すると思っていました.130,000を超える観測があり、一部の観測には「ID:」と番号の間に空白「」がないという問題があることに気づきませんでした。たとえば、上記のデータでは、「ID:96」はコロンと数字の間に空白がありません。明らかに、次の警告メッセージが表示されました。

Warning message:
  In matrix(unlist(temp), ncol = 5, byrow = TRUE) :
  data length [796454] is not a sub-multiple or multiple of the number of rows [159291]

明らかに、strsplit の出力は次の 2 つの形式を取るため、strsplit を適切な通常の列に強制することはできません。

[1] "ID:"     "10"      "DAY:"    "6/10/13" "S"   #when there is whitespace
[1] "ID:96"  "DAY:"   "6/8/13" "T"   #when there isn't whitespace

これを回避するために、「ID:」の後にスペースを入れることができればうまくいくと考えて、これを行いました。

df$obs <- gsub("ID:", "ID: ", df$obs)

しかし、strsplit を実行したとき、データを分割する 2 つの場所として二重の空白が認識されたため、これは機能しませんでした。

idnumber、date、identifier の個別の列を使用して元の df に強制的に戻すことができる複数の strsplits の解決策を誰かが知っていれば、それは素晴らしいことです。

編集:申し訳ありませんが、再現可能な例のデータを追加するのを忘れました:

df<-structure(list(duration = c(1.80176, 1.8685, 0.233562, 5.53876, 
                        3.4367, 0.533856, 2.30225, 2.77942), obs = structure(c(1L, 1L, 
                                                                               1L, 2L, 2L, 2L, 2L, 2L), .Label = c("ID: 10 DAY: 6/10/13 S", 
                                                                                                                   "ID:96 DAY: 6/8/13 T"), class = "factor"), another = structure(c(3L, 
                                                                                                                                                                                    2L, 5L, 5L, 1L, 4L, 3L, 2L), .Label = c("blue", "green", "orange", 
                                                                                                                                                                                                                            "pink", "yellow"), class = "factor")), .Names = c("duration", 
                                                                                                                                                                                                                                                                              "obs", "another"), class = "data.frame", row.names = c(NA, -8L
                                                                                                                                                                                                                                                                              ))
4

2 に答える 2

6

あなたがそのデータ入力担当者を解雇した後、ここで正規表現を使用してデータを取得することを検討するかもしれません。まず、これは「obs」列のデータです(コメントから追加の値を追加します)

obs<-c("ID: 10 DAY: 6/10/13 S", "ID: 10 DAY: 6/10/13 S", "ID: 10 DAY: 6/10/13 S", 
"ID:96 DAY: 6/8/13 T", "ID:96 DAY: 6/8/13 T", "ID:96 DAY: 6/8/13 T", 
"ID:96 DAY: 6/8/13 T", "ID:96 DAY: 6/8/13 T", "ID: 84DAY: 6/8/13 T")

次に、次のコマンドでデータをキャプチャできます

m<-regexpr("ID:\\s*(\\d+) ?DAY: (\\d+/\\d+/\\d+) (S|T)", obs, perl=T)

次に、ヘルパー関数regcapturedmatches()を使用して、キャプチャされた一致を抽出します (regmatches()キャプチャ グループの場合と同様に機能します)。

do.call(rbind, regcapturedmatches(obs,m))

#      [,1] [,2]      [,3]
# [1,] "10" "6/10/13" "S" 
# [2,] "10" "6/10/13" "S" 
# [3,] "10" "6/10/13" "S" 
# [4,] "96" "6/8/13"  "T" 
# [5,] "96" "6/8/13"  "T" 
# [6,] "96" "6/8/13"  "T" 
# [7,] "96" "6/8/13"  "T" 
# [8,] "96" "6/8/13"  "T" 
# [9,] "84" "6/8/13"  "T"

これは、値のマトリックスを返します。その後、これらの文字値を好きなように処理できます。それらを正しいクラスに変換して、data.frame にアタッチできます。

ただし、を使用したい場合はstrsplit、「:」または「:」の前にオプションがあるスペースで分割できます。

do.call(rbind, strsplit(obs,"(:|:?\\s+)", obs))

#      [,1] [,2]    [,3]     [,4]      [,5]
# [1,] "ID" "10"    "DAY"    "6/10/13" "S" 
# [2,] "ID" "10"    "DAY"    "6/10/13" "S" 
# [3,] "ID" "10"    "DAY"    "6/10/13" "S" 
# [4,] "ID" "96"    "DAY"    "6/8/13"  "T" 
# [5,] "ID" "96"    "DAY"    "6/8/13"  "T" 
# [6,] "ID" "96"    "DAY"    "6/8/13"  "T" 
# [7,] "ID" "96"    "DAY"    "6/8/13"  "T" 
# [8,] "ID" "96"    "DAY"    "6/8/13"  "T" 
# [9,] "ID" "84DAY" "6/8/13" "T"       "ID"

これは、最新の新しい不良データ行まで機能します。

于 2014-07-03T14:21:01.057 に答える