2012-02-09 8 views
10

データフレームの列または行の名前を変更するために、データフレームに名前のベクトルを与える方法がわかります。データフレーム内の各列のクラスを変更する名前のベクトルを提供する同様のメソッドがありますか?これは、colClassesを使用してread.tableを使用してデータフレームを読み込むときに実行できます。データフレームがRの中で作られたらどうでしょうか?は、データフレームの「クラス」にベクトルを供給します。

DF <- as.data.frame(matrix(rnorm(25), 5, 5)) 
str(DF) #all numeric modes 

names(DF) <- c("A", "A2", "B", "B2", "Z") #I want something like this for classes 
some_classes_function_like_names(DF) <- c(rep("character", 3), rep("factor", 2)) 

#I can do it like this but this seems inefficient 
DF[, 1:3] <- lapply(DF[, 1:3], as.character) 
DF[, 4:5] <- lapply(DF[, 4:5], as.factor) 

str(DF) 

EDIT:sapplyが理にかなっていないので、上記のsapplyをlapplyに変更しました。

EDIT 2:同様

答えて

5

を十分でユーザー定義関数を記述するための方法があればclass(x) <- "factor"が働かないようでないとどちらもas(x, "factor")を行いますので、私がやっての直接的な方法を知りませんあなたが欲しいもの。

...しかし、もう少し明示的な方法は次のとおりです。

# Coerces data.frame columns to the specified classes 
colClasses <- function(d, colClasses) { 
    colClasses <- rep(colClasses, len=length(d)) 
    d[] <- lapply(seq_along(d), function(i) switch(colClasses[i], 
     numeric=as.numeric(d[[i]]), 
     character=as.character(d[[i]]), 
     Date=as.Date(d[[i]], origin='1970-01-01'), 
     POSIXct=as.POSIXct(d[[i]], origin='1970-01-01'), 
     factor=as.factor(d[[i]]), 
     as(d[[i]], colClasses[i]))) 
    d 
} 

# Example usage 
DF <- as.data.frame(matrix(rnorm(25), 5, 5)) 
DF2 <- colClasses(DF, c(rep("character", 3), rep("factor", 2))) 
str(DF2) 

DF3 <- colClasses(DF, 'Date') 
str(DF3) 

物事のカップル:必要に応じて、あなたはより多くのケースを追加することができます。関数の最初の行では、単一のクラス名で呼び出すことができます。 switchの最後の「デフォルト」の場合、as関数が呼び出されます。

toCls <- function(x, cls) do.call(paste("as", cls, sep = "."), list(x)) 
replace(DF,, Map(toCls, DF, cls)) 

第二の例:

+0

@ Tommy私は「あなたはすでにそれを簡単に行う基本機能があります」という答えを期待していました。あなたの機能はうまくいきます。私は自分自身のための便利な関数として.First()にそれを投げるつもりです。私は実際には、Rコアチームがまだread.tableの一部であるように見えるので、このようなことをまだ実装していないことに少し驚いています。ありがとうございました。 –

+0

@タイラー私はあなたの驚きを共有しました。私はずっとこれを行うための基底関数を探し求めていましたし、通常はその場でいくつかの特別なアプローチを取っています。 Rコアのチームがこれを基本とみなすなら、それは素晴らしいことでしょう。 – digitalmaps

8

はこれを試してみてください。また、この例を試してみてください(クラスが変更されない列にはNAを使用できます)。動物園のパッケージはデフォルトの起点を持つas.Dateのバージョンを提供するので、私たちは独自にas.POSIXct2を定義して、原点を指定しなくても済むようにします。

library(zoo) # supplies alternate as.Date with a default origin 
as.NA <- identity 
as.POSIXct2 <- function(x) as.POSIXct(x, origin = "1970-01-01") 

cls2 <- c("character", "Date", NA, "factor", "POSIXct2") 
replace(DF,, Map(toCls, DF, cls2)) 

なお、その唯一の"Date"または"POSIXct"に番号を変換するときが起源の考慮事項があり、"2000-01-01"ような文字列を変換する際に、このような状況のために、我々はする必要はありませんので、何の起源は、どのような場合に指定する必要はないだろうという動物園をロードすると、as.POSIXctという独自のバージョンは必要ありません。

EDIT:別の例を追加しました。

関連する問題