0

私はRにかなり慣れていませんが、これは私が答えを見つけることができなかった特定の問題であるようです.

私のプログラムはいくつかのデータを読み取り、そのデータの特定の列を、渡す列番号のベクトルに基づいていくつかのデータフレームの1つに再バインドします。次のようになります。

filename <- c("vector", "full", "of", "filenames")
colVal <- (32)    
InMat <- data.frame()
for (i in 1:length(filename)){
  file <- read.table(filename[i], header=TRUE, fill=TRUE, stringsAsFactors=FALSE)
  InMat <- rbind(InMat, file[c(2:dim(file)[1], colVal)])
  #...other matricies...
}

私の問題は、必要な列が 1 つしかない場合、つまり colVal が 1 つの値を取る場合にあります。この場合、InMat は本質的に必要なものから転置されていることがわかります。さらに悪いことに、複数のファイルを読み取ると、転置された目的の列が再バインドされるため、読み込んでいるファイルの数と同じ数の行が取得され、各ファイルの目的の各列にある行と同じ数の列が得られます。

必要な列が 2 つある場合 (つまり、colVal が 2 つ以上の値を取る)、期待どおりに動作するようです (つまり、列が読み取られて列として InMat に格納され、追加の各ファイルの列が下に格納されます)。

私の質問は、目的の列値が 1 つだけ渡された場合に rbind の動作が異なるのはなぜですか、また、これを回避する簡単な方法 (読む; 不格好な if または for ループを追加してチェックしない) がある場合です。

ありがとう!

4

2 に答える 2

1

簡単な答え: [.data.frame([データ フレームの演算子) デフォルトでは、出力を可能な限り低い次元に変換します (引数を介してdrop=TRUE)。1 つの列だけをプルしている場合は、ベクトルに変換され、他のベクトルを含むマトリックスがマトリックスに作成rbindされます。2 つ以上の列を抽出すると、データ フレームが得られるため、 の出力rbindはデータ フレームです。

簡単な修正は、次の行を変更することです。

InMat <- rbind(InMat, file[c(2:dim(file)[1], colVal)]) #old line
InMat <- rbind(InMat, file[c(2:dim(file)[1], colVal),drop=FALSE]) #new line

これをコーディングするより R に似た方法は、一度使用lapplyして呼び出すことです。rbindR はコピーによる代入であるため、連結/追加を繰り返してオブジェクトを成長させるのは非常に非効率的です ( R Infernoの 2 番目の円を参照)。

filename <- c("vector", "full", "of", "filenames")
colVal <- (32)    
dfm <- lapply(filename, read.table
  , header=TRUE, fill=TRUE, stringsAsFactors=FALSE)
dfm <- lapply(dfm,`[`,colVal)
dfm <- do.call(rbind,dfm)

抽出する列の位置が事前にわかっている場合は、colClasses引数を使用しread.tableて、テーブル全体の読み取りをスキップできます。

filename <- c("vector", "full", "of", "filenames")
colVal <- 32
cc <- rep.int("NULL",40) #where 40 is # of columns in table
cc[colVal] <- NA 
dfm <- lapply(filename, read.table
  , header=TRUE, fill=TRUE, colClasses=cc, stringsAsFactors=FALSE)
dfm <- do.call(rbind,dfm)
于 2013-03-14T18:23:25.747 に答える
0

When you take only one column it becomes a vector. It would be better if you just appended all the values into a vector instead of a matrix

InVec <- c()
for (i in 1:length(filename)){
  file <- read.table(filename[i], header=TRUE, fill=TRUE, stringsAsFactors=FALSE)
  InVec <- c(InVec, file[-1, colVal)])
  #...other matricies...
}

Using c() will be much faster than rbind as well

于 2013-03-14T15:20:09.880 に答える