2011-08-09 2 views
4

cut関数を使用して、最大/最小範囲を使用してデータをグループに分割しています。ここで私が使用していたコードの例を次に示します。値が属するファクタグループを特定する方法を教えてください。

# sample data frame - used to identify intial groups 
testdf <- data.frame(a = c(1:100), b = rnorm(100)) 

# split into groups based on ranges 
k <- 20 # number of groups 
# split into groups, keep code 
testdf$groupCode <- cut(testdf$b, breaks = k, labels = FALSE) 
# store factor information 
testdf$group <- cut(testdf$b, breaks = k)      
head(testdf) 

私は別のデータフレームまでを分割する識別要因のグループ化を使用したいが、私はこれに対処するための要素を使用するかどうかはわかりません。私は次のように私のコードの構造は、大きくすべきだと思います。

# this is the data I want to categorize based on previous groupings 
datadf <- data.frame(a = c(1:100), b = rnorm(100)) 
datadf$groupCode <- function(x){return(groupCode)} 

私は次のように係数データが​​構造体であることがわかり、私はそれを適切に使用する方法がわからない:

testdf$group[0] 
factor(0) 
20 Levels: (-2.15,-1.91] (-1.91,-1.67] (-1.67,-1.44] (-1.44,-1.2] ... (2.34,2.58] 

2つの関数私が使って実験されていること(ただし、動作しません)以下の通りである。

# get group code 
nearestCode <- function(number, groups){ 
    return(which(abs(groups-number)== min(abs(groups-number)))) 
} 
nearestCode(7, testdf$group[0]) 

をし、またwhich機能を使って実験します。

which(7, testdf$group[0]) 

グループ化を識別して別のデータフレームに適用する最も良い方法は何ですか?

+0

マイナーポイント: 'return 1'はおそらくタイプミスですか?そしてあなたは本当に 'lapply'を使って列に単一の値を代入していますか、それとも別の意味ですか? – joran

+0

@joran - 良い点;申し訳ありませんが 'return 1'はタイプミスでしたが、私は擬似コードをスケッチしようとしていました。 'lapply'は私が編集した使い方の誤解でした。 – djq

+1

データの範囲を等しい長さに分割したい場合は、 'span <-diff(range(x));を使用します。 breaks = seq.int(min(x)-span/1000、max(x)+ span/1000、by = span/n) '。次に、数値ベクトルを保存します。これは 'cut'を行う方法の一種で、' cut.default'とタイプすると実際のコードを見ることができます。 –

答えて

7

私が使用しているだろう:

testdf$groupCode <- cut(testdf$b, breaks = 
          quantile(testdf$b, seq(0,1, by=0.05), na.rm=TRUE)) 
grpbrks <- quantile(testdf$b, seq(0,1, by=0.05), na.rm=TRUE) 

を次にあなたが使用することができます。

findInterval(newdat$newvar, grpbrks) # to group new data 

をそして、あなたはその後、ラベルやデータから休憩を回復すると周りのネジする必要はありません。

について考える、私はあなたにも使うことができると思います:いくつかの正規表現で悪ふざけ

cut(newdat$newvar, grpbrks) # more isomorphic to original categorization I suppose 
+0

+1ニース........ – Andrie

+0

ありがとう@DWin、それは非常にコンパクトです。私は分数の使用を避けようとしています - 範囲を使ってブレークを定義して、 'findInterval'を使うことができる方法はありますか? – djq

+0

私の独自のサブ質問に答えるだけです。 'step =(max(testdf $ b) - min(testdf $ b))/ k; breaks = rep(1:k * breaks) ' – djq

2

が実際にcut起因するオブジェクトの値を返すの唯一の方法であると思われます。

cut_breaks <- function(x){ 
    first <- as.numeric(gsub(".{1}(.+),.*", "\\1", levels(x))[1]) 
    other <- as.numeric(gsub(".+,(.*).{1}", "\\1", levels(x))) 
    c(first, other) 
} 

set.seed(1) 
x <- rnorm(100) 

cut1 <- cut(x, breaks=20) 
cut_breaks(cut1) 
[1] -2.2200 -1.9900 -1.7600 -1.5300 -1.2900 -1.0600 -0.8320 -0.6000 -0.3690 
[10] -0.1380 0.0935 0.3250 0.5560 0.7870 1.0200 1.2500 1.4800 1.7100 
[19] 1.9400 2.1700 2.4100 

levels(cut1) 
[1] "(-2.22,-1.99]" "(-1.99,-1.76]" "(-1.76,-1.53]" "(-1.53,-1.29]" 
[5] "(-1.29,-1.06]" "(-1.06,-0.832]" "(-0.832,-0.6]" "(-0.6,-0.369]" 
[9] "(-0.369,-0.138]" "(-0.138,0.0935]" "(0.0935,0.325]" "(0.325,0.556]" 
[13] "(0.556,0.787]" "(0.787,1.02]" "(1.02,1.25]"  "(1.25,1.48]"  
[17] "(1.48,1.71]"  "(1.71,1.94]"  "(1.94,2.17]"  "(2.17,2.41]"  

あなたは、あなたの第二のカットを作るためにbreaks=パラメータを使用してcutにこれらのブレーク値を渡すことができます。

次のコードは、必要なねじ込みを行います。