2011-03-11 14 views
1

私はこの問題の解決策をオンラインで見つけることができませんでした。ここ はそれがあります:一般的に言えば扱う数字を文字として扱います

#Construct test dataframe 
tf <- data.frame(1:3,4:6,c("A","A","A")) 

#Try the apply function I'm trying to use 
test <- apply(tf,2,function(x) if(is.numeric(x)) mean(x) else unique(x)[1]) 

#Look at the output--all columns treated as character columns... 
test 

#Look at the format of the original data--the first two columns are integers. 
str(tf) 

、私は、行/列が含まれているデータの種類に基づいて、行/列の上にどのような機能I applyを区別します。

ここでは、列が数値の場合は単純なmean、列が文字列の場合は最初のuniqueの値が必要です。ご覧のとおり、applyはすべての列を文字として扱います。

答えて

4

sapply ... apply(dtf, 2, fun)を使用しないでください。専用の関数を記述してください。さらに、あなたのキャラクターはあなたが考えるかもしれないようにキャラクターではありません - getOption("stringsAsFactors")を実行し、あなた自身のために見てください。

sapply(tf, class) 
      X1.3    X4.6 c..A....A....A.. 
     "integer"  "integer"   "factor" 
sapply(tf, storage.mode) 
      X1.3    X4.6 c..A....A....A.. 
     "integer"  "integer"  "integer" 

EDIT

あるいはさらに良い - lapplyを使用します。

fn <- function(x) { 
    if(is.numeric(x) & !is.factor(x)) { 
    mean(x) 
    } else if (is.character(x)) { 
    unique(x)[1] 
    } else if (is.factor(x)) { 
    as.character(x)[1] 
    } 
} 

dtf <- data.frame(a = 1:3, b = 4:6, c = rep("A", 3), stringsAsFactors = FALSE) 
dtf2 <- data.frame(a = 1:3, b = 4:6, c = rep("A", 3), stringsAsFactors = TRUE) 

as.data.frame(lapply(dtf, fn)) 
    a b c 
1 2 5 A 
as.data.frame(lapply(dtf2, fn)) 
    a b c 
1 2 5 A 
+0

これはまさに答えでした - ありがとう!貢献した他の人たちへの感謝: – Aaron

+0

列 'c'のクラスはデフォルトで' factor'になっているので、 'stringsToFactors = FALSE'を追加するのを忘れました。 'options(stringsAsFactors = FALSE)'を設定したい場合は、 'factor'を取得します。助言されます。 – aL3xa

2

あなたは(lapply使用したい)またはsapply()、()を適用していません。 data.frameはフードの下にあるリストで、何かをする前にマトリックスに変換しようとします。データフレーム内の少なくとも1つの列は文字であるため、他のすべての列もその行列を形成する際に文字に強制変換されます。

+0

そうです、行列は1つの型のデータだけを保持できます: 'is.atomic(matrix)'は 'TRUE'を返します。 – aL3xa

3

私は文法的に簡単な解決策のために、ここに有用plyrパッケージからnumcolwisecatcolwise機能を見つける:

まず集約を行う際に醜い列名を避けるために、の列に名前を付けてみましょう:

tf <- data.frame(a = 1:3,b=4:6, d = c("A","A","A")) 

そして、あなたはこのワンライナーであなたの希望する結果を得る:

> cbind(numcolwise(mean)(tf), catcolwise(function(z) unique(z)[1])(tf)) 
    a b d 
1 2 5 A 

説明:numcolwise(f)は、その引数(この場合はfmeanファンクション)をデータフレームを受け取り、fをデータフレームの数値列にのみ適用する関数に変換します。同様に、catcolwiseは、その関数の引数を、カテゴリ型の列に対してのみ動作する関数に変換します。

関連する問題