3

data.frame を指定して、すべての列が同じ「クラス」であるかどうかをテストしたいと思います。もしそうなら、data.frameをそのままにしておきたいです。そうでない場合は、最初の変数クラスに一致するすべての列を保持し、そのクラスではない列を削除したいと思います。例外は、私の目的では、整数と数値が等しいということです。

例えば:

dat <- data.frame(numeric,numeric,integer,factor) 

だろう:

data.frame(numeric,numeric,integer) 

さらに

dat <- data.frame(character,character,integer)

だろう:

data.frame(character,character) 

そして最後に:

dat <- data.frame(numeric,numeric,numeric,factor)

だろう:

data.frame(numeric,numeric,numeric)
4

3 に答える 3

4

私はこれをします:

dat <- data.frame(
  a=as.integer(1:26), b=as.integer(26:1), c=as.numeric(1:26), d=as.factor(1:26)
)

2 つのヘルパー関数を作成します。

is.numint <- function(x)is.numeric(x) || is.integer(x)
is.charfact <- function(x)is.character(x) || is.factor(x)

数値列のみを返す:

head(dat[, sapply(dat, is.numint)])
    a  b  c
1   1 26  1
2   2 25  2
3   3 24  3
4   4 23  4
5   5 22  5

因子列のみを返す:

head(dat[, sapply(dat, is.charfact), drop=FALSE])
  d
1 1
2 2
3 3
4 4
5 5
6 6

このアプローチを組み合わせて、関数を書き直します。

dropext <- function(x){
  is.numint <- function(x)is.numeric(x) || is.integer(x)
  is.charfact <- function(x)is.character(x) || is.factor(x)
  cl <- rep(NA, length(x))
  cl[sapply(x, is.numint)] <- "num"
  cl[sapply(x, is.charfact)] <- "char"
  x[, cl == unique(cl)[1], drop=FALSE]
}

dropext(dat)
    a  b  c
1   1 26  1
2   2 25  2
3   3 24  3
4   4 23  4
5   5 22  5
于 2012-11-02T20:43:03.893 に答える
3

どうですか:

if(length(unique(cl <- sapply(dat, class))) > 1 && 
   any(!sapply(dat, is.numeric))) {
    dat <- dat[ , which(cl == cl[1]), drop = FALSE]
}

これは、次の例では次のことを前提としています。

dat2 <- data.frame(A = factor(sample(LETTERS, 26, replace = TRUE)),
                   B = factor(sample(LETTERS, 26, replace = TRUE)),
                   C = sample(LETTERS, 26, replace = TRUE),
                   dat, stringsAsFactors = FALSE)


> sapply(dat2, class)
               A                B                C 
        "factor"         "factor"      "character" 
as.integer.1.26. as.integer.26.1. as.numeric.1.26. 
       "integer"        "integer"        "numeric" 

因子変数のみが必要です。つまり、文字変数と因子変数を区別する必要があります。これは、コードが実行しているように見えることです。

この例では、

if(length(unique(cl <- sapply(dat2, class))) > 1 &&
   any(!sapply(dat2, is.numeric))) {
    dat2 <- dat2[ ,which(cl == cl[1]), drop = FALSE]
}

その結果、

> head(dat2)
  A B
1 D G
2 P D
3 C T
4 X F
5 N R
6 A E
> sapply(dat2, class)
       A        B 
"factor" "factor"

datで、上記のステートメントif()は変更されませんdat

>     if(length(unique(cl <- sapply(dat, class))) > 1 && 
+         any(!sapply(dat, is.numeric))) {
+         dat <- dat[ , which(cl == cl[1]), drop = FALSE]
+     }
> head(dat)
  as.integer.1.26. as.integer.26.1. as.numeric.1.26.
1                1               26                1
2                2               25                2
3                3               24                3
4                4               23                4
5                5               22                5
6                6               21                6
于 2012-11-02T21:04:31.463 に答える
1

解説とあなたの答えに感謝します。最終的に必要なのは、整数と数値を区別しない class() 関数だけでした。これは、単純なラッパーで実現できます。

class.wrap <- function(x) {
test <- class(x) 
if(test == "integer") test <- "numeric"
return(test)
} 
于 2012-11-02T22:18:37.057 に答える