2

他のさまざまな言語から来て、R は強力で直感的だと思いますが、そのパフォーマンスには興奮していません。そこで、私が書いたスニペットを改善して、R でより適切にコーディングする方法を学ぶことにしました。

これは私が書いた関数で、ベクトルがバイナリ値 (2 つの異なる値または 1 つの値) であるかどうかを判断しようとしています。

isBinaryVector <- function(v) {
  if (length(v) == 0) {
    return (c(0, 1))
  }
  a <- v[1]
  b <- a
  lapply(v, function(x) { if (x != a && x != b) {if (a != b) { return (c()) } else { b = x }}})
  if (a < b) {
    return (c(a, b))
  } else {
    return (c(b, a))
  }
}

編集: この関数は、ベクトルを調べてから、c()バイナリ値でない場合は戻り、バイナリ値のc(a, b)場合は a が小さい値で b が大きい値を返すことが期待されます (a == b の場合、c(a, a).

  A B C
1 1 1 0
2 2 2 0
3 3 1 0

私はlapplyこれisBinaryVectorをして取得します:

$A
[1] 1 1

$B
[1] 1 1

$C
[1] 0 0

中程度のサイズのデータ​​セット (約 1800 * 3500、それらの 2/3 はバイナリ値) にかかった時間は約 15 秒です。セットには浮動小数点数のみが含まれます。

とにかく私はこれをより速く行うことができますか?

ご意見ありがとうございます。

4

2 に答える 2

8

基本的に、ベクトルに 2 つの一意の値がある場合に TRUE を返し、それ以外の場合に FALSE を返す関数を作成しようとしています。

これを試して:

> dat <- data.frame(
+   A = 1:3,
+   B = c(1, 2, 1), 
+   C = 0
+ )
> 
> sapply(dat, function(x)length(unique(x))==2)
    A     B     C 
FALSE  TRUE FALSE 

次に、最小値と最大値を取得します。関数rangeはこれを行います。そう:

> sapply(dat, range)
     A B C
[1,] 1 1 0
[2,] 3 2 0

これで、大量のデータに対しても、理解しやすく、非常に高速な小さな関数を作成するためのすべての要素が揃いました。

isBinary <- function(x)length(unique(x))==2

binaryValues <- function(x){
  if(isBinary(x)) range(x) else NA
}

sapply(dat, binaryValues)

$A
[1] NA

$B
[1] 1 2

$C
[1] NA
于 2012-04-19T14:52:02.270 に答える
4

この関数は、ベクトル(またはデータフレームの列)に対してtrueまたはfalseを返します。

is.binary <- function(v) {
  x <- unique(v)
  length(x) - sum(is.na(x)) == 2L
}

この投稿も見てください

私はそのようなものを使用して列のインデックスを取得します:

bivalued <- apply(my.data.frame, 2, is.binary)

nominal <- my.data.frame[,!bivalued]
binary <- my.data.frame[,bivalued]

サンプルデータ:

my.data.frame <- data.frame(c(0,1), rnorm(100), c(5, 19), letters[1:5], c('a', 'b'))
> apply(my.data.frame, 2, is.binary)
     c.0..1.   rnorm.100.     c.5..19. letters.1.5.  c..a....b.. 
        TRUE        FALSE         TRUE        FALSE         TRUE 
于 2012-04-19T14:42:44.140 に答える