2

コマンドcut()( example(cut)) のサンプル メニュー、具体的には次の部分を見ています。

cut> aaa <- c(1,2,3,4,5,2,3,4,5,6,7)

cut> cut(aaa, 3)
[1] (0.994,3] (0.994,3] (3,5]     (3,5]     (3,5]     (0.994,3]
[7] (3,5]     (3,5]     (3,5]     (5,7.01]  (5,7.01] 
Levels: (0.994,3] (3,5] (5,7.01]

cut> cut(aaa, 3, dig.lab = 4, ordered = TRUE)
[1] (0.994,2.998] (0.994,2.998] (2.998,5.002] (2.998,5.002]
[5] (2.998,5.002] (0.994,2.998] (2.998,5.002] (2.998,5.002]
[9] (2.998,5.002] (5.002,7.006] (5.002,7.006]
Levels: (0.994,2.998] < (2.998,5.002] < (5.002,7.006]

cut> ## one way to extract the breakpoints
cut> labs <- levels(cut(aaa, 3))

cut> cbind(lower = as.numeric( sub("\\((.+),.*", "\\1", labs) ),
cut+       upper = as.numeric( sub("[^,]*,([^]]*)\\]", "\\1", labs) ))
     lower upper
[1,] 0.994  3.00
[2,] 3.000  5.00
[3,] 5.000  7.01

間隔が右側で閉じている場合(上記のように)、次を使用してデータのブレークポイントを抽出する方法を示しています。cbind()

ここで、データがカットされると仮定しましょう。ただし、間隔が左側で閉じていることを示しています。

cut(aaa, 3, dig.lab = 4, ordered = TRUE, right = FALSE)

同じコマンドを使用してブレークポイントを抽出するにはどうすればよいcbind()ですか? (他にも方法があればよろしくお願いします)

4

1 に答える 1

7

パターンに次のようなものを使用し、gsub代わりに"\\[|\\]|\\(|\\)".

例。

out <- levels(cut(aaa, 3, dig.lab = 4, ordered = TRUE, right = FALSE))
gsub("\\[|\\]|\\(|\\)", "", out)
# [1] "0.994,2.998" "2.998,5.002" "5.002,7.006"

そして、そのデータを読み取る簡単な方法は次のとおりです。

read.csv(text = gsub("\\[|\\]|\\(|\\)", "", out), header = FALSE)
#      V1    V2
# 1 0.994 2.998
# 2 2.998 5.002
# 3 5.002 7.006

参考までに: 間隔が左側または右側で閉じているかどうかにかかわらず、同じパターンが機能します。元の例を使用して:

labs <- levels(cut(aaa, 3))
labs
# [1] "(0.994,3]" "(3,5]"     "(5,7.01]" 
read.csv(text = gsub("\\[|\\]|\\(|\\)", "", labs), header = FALSE)
#      V1   V2
# 1 0.994 3.00
# 2 3.000 5.00
# 3 5.000 7.01

代替手段としては、 を使用する前に最初と最後の文字を削除するだけでよいため、正規表現に煩わされることなくread.csv簡単に使用することもできます(それが気に入らない場合)。substr

substr(labs, 2, nchar(labs)-1)
# [1] "0.994,3" "3,5"     "5,7.01" 

更新: まったく異なる代替手段

R がこれらの値を計算し、表示される出力を生成するために関数の一部として格納する必要があることは明らかであるため、関数を操作してさまざまなものを出力させることはそれほど難しくありません。

のコードを見るとcut.default、最後の数行が次のようになっていることがわかります。

if (codes.only) 
    code
else factor(code, seq_along(labels), labels, ordered = ordered_result)

最後の数行を、最初の項目としてのlist出力を含むa を出力するように変更するのは非常に簡単で、計算された範囲 (貼り付けられた.cutcutfactor labels

たとえば、このリンクに投稿した Gist では、これらの行を次のように変更しました。

if (codes.only) 
  FIN <- code
else FIN <- factor(code, seq_along(labels), labels, ordered = ordered_result)
list(output = FIN, ranges = data.frame(lower = ch.br[-nb], upper = ch.br[-1L]))

今、比較してください:

cut(aaa, 3)
#  [1] (0.994,3] (0.994,3] (3,5]     (3,5]     (3,5]     (0.994,3] (3,5]     (3,5]    
#  [9] (3,5]     (5,7.01]  (5,7.01] 
# Levels: (0.994,3] (3,5] (5,7.01]
CUT(aaa, 3)
# $output
# [1] (0.994,3] (0.994,3] (3,5]     (3,5]     (3,5]     (0.994,3] (3,5]     (3,5]    
# [9] (3,5]     (5,7.01]  (5,7.01] 
# Levels: (0.994,3] (3,5] (5,7.01]
# 
# $ranges
#   lower upper
# 1 0.994     3
# 2     3     5
# 3     5  7.01

そして、right = FALSE

cut(aaa, 3, dig.lab = 4, ordered = TRUE, right = FALSE)
#  [1] [0.994,2.998) [0.994,2.998) [2.998,5.002) [2.998,5.002) [2.998,5.002)
#  [6] [0.994,2.998) [2.998,5.002) [2.998,5.002) [2.998,5.002) [5.002,7.006)
# [11] [5.002,7.006)
# Levels: [0.994,2.998) < [2.998,5.002) < [5.002,7.006)
CUT(aaa, 3, dig.lab = 4, ordered = TRUE, right = FALSE)
# $output
#  [1] [0.994,2.998) [0.994,2.998) [2.998,5.002) [2.998,5.002) [2.998,5.002)
#  [6] [0.994,2.998) [2.998,5.002) [2.998,5.002) [2.998,5.002) [5.002,7.006)
# [11] [5.002,7.006)
# Levels: [0.994,2.998) < [2.998,5.002) < [5.002,7.006)

# $ranges
#   lower upper
# 1 0.994 2.998
# 2 2.998 5.002
# 3 5.002 7.006
于 2013-10-30T17:15:40.827 に答える