7

次のコマンドを使用して、大きなデータ ファイルを R に読み込みました。

data <- as.data.set(spss.system.file(paste(path, file, sep = '/')))

データ セットには、属してはならない列が含まれており、空白のみが含まれています。この問題は、R が SPSS ファイル ( Source )に添付された変数ラベルに基づいて新しい変数を作成することに関係しています。

残念ながら、問題を解決するために必要なオプションを特定できませんでした。私は、foreign::read.spss、memisc:spss.system.file、および Hemisc::spss.get のすべてを試しましたが、うまくいきませんでした。

代わりに、データ セット全体 (ゴースト列を含む) を読み込み、不要な変数を手動で削除したいと考えています。ゴースト列には空白しか含まれていないため、一意の観測値の数が 1 である変数を data.table から削除したいと思います。

私のデータは大きいので、data.table 形式で保存されます。各列の一意の観測の数を確認し、一意の観測を 1 つだけ含む列を削除する簡単な方法を決定したいと思います。

require(data.table)

### Create a data.table
dt <- data.table(a = 1:10,
                 b = letters[1:10],
                 c = rep(1, times = 10))

### Create a comparable data.frame
df <- data.frame(dt)

### Expected result
unique(dt$a)

### Expected result
length(unique(dt$a))

ただし、大きなデータ ファイルの obs の数を計算したいので、各列を名前で参照することは望ましくありません。私は eval(parse()) のファンではありません。

### I want to determine the number of unique obs in
  # each variable, for a large list of vars
lapply(names(df), function(x) {
    length(unique(df[, x]))
})

### Unexpected result
length(unique(dt[, 'a', with = F]))  # Returns 1

私には問題があるようです

dt[, 'a', with = F]

クラス「data.table」のオブジェクトを返します。このオブジェクトは 1 つの変数を含む data.table であるため、このオブジェクトの長さが 1 であることは理にかなっています。data.frames は実際には単なる変数のリストであることを知っているので、この場合、リストの長さはちょうど 1 です。

data.frame の方法を使用して、ソリューションを修正する方法の擬似コードを次に示します。

for (x in names(data)) {
  unique.obs <- length(unique(data[, x]))
  if (unique.obs == 1) {
    data[, x] <- NULL
  }
}

data.table の列ごとに一意の観測値の数をより効率的に求める方法についての洞察をいただければ幸いです。または、data.table 内に一意の観測が 1 つしかない場合に観測を削除する方法を推奨できる場合は、さらに良いでしょう。

4

4 に答える 4

9

アップデート:uniqueN

バージョン 1.9.6 の時点で、このソリューションの組み込み (最適化) バージョンであるuniqueN関数があります。これは次のように簡単です。

dt[ , lapply(.SD, uniqueN)]

各列の一意の値の数を見つけたい場合は、次のようになります

 dt[, lapply(.SD, function(x) length(unique(x)))]
##     a  b c
## 1: 10 10 1

関数を機能させるには、with=FALSE[.data.tableで使用するか、単に代わりに使用する必要があります(同様[[に読んでください...)fortune(312)

lapply(names(df) function(x) length(unique(dt[, x, with = FALSE])))

また

 lapply(names(df) function(x) length(unique(dt[[x]])))

動作します

一歩で

dt[,names(dt) := lapply(.SD, function(x) if(length(unique(x)) ==1) {return(NULL)} else{return(x)})]


 # or to avoid calling `.SD` 

dt[, Filter(names(dt), f = function(x) length(unique(dt[[x]]))==1) := NULL]
于 2013-04-16T02:44:35.500 に答える
4

他の回答のアプローチは良いです。楽しみのために、ミックスに追加する別の方法:

for (i in names(DT)) if (length(unique(DT[[i]]))==1) DT[,(i):=NULL]

または、列名が重複している可能性がある場合:

for (i in ncol(DT):1) if (length(unique(DT[[i]]))==1) DT[,(i):=NULL]

注意:(i)の LHSでは、 という名前の列ではなく:=、 の値を使用するのがコツです。i"i"

于 2013-04-16T08:47:28.237 に答える
1

これがあなたの中心的な問題の解決策です(私はそれが正しいことを願っています)。

require(data.table)

### Create a data.table
dt <- data.table(a = 1:10,
                 b = letters[1:10],
                 d1 = "",
                 c = rep(1, times = 10),
                 d2 = "")
dt
     a b d1 c d2
 1:  1 a    1   
 2:  2 b    1   
 3:  3 c    1   
 4:  4 d    1   
 5:  5 e    1   
 6:  6 f    1   
 7:  7 g    1   
 8:  8 h    1   
 9:  9 i    1   
10: 10 j    1   

まず、値がまったくない2 つの列d1を紹介します。d2削除したいものですよね?その場合、それらの列を特定し、dt.

only_space <- function(x) {
  length(unique(x))==1 && x[1]==""
}
bolCols <- apply(dt, 2, only_space)
dt[, (1:ncol(dt))[!bolCols], with=FALSE]

どういうわけか、もっと単純化できる気がします...

出力:

     a b c
 1:  1 a 1
 2:  2 b 1
 3:  3 c 1
 4:  4 d 1
 5:  5 e 1
 6:  6 f 1
 7:  7 g 1
 8:  8 h 1
 9:  9 i 1
10: 10 j 1
于 2013-04-16T02:41:15.100 に答える
0

「dplyr」ライブラリを使用してそれを行う簡単な方法があり、次に select 関数を次のように使用します。

ライブラリ(dplyr)

newdata <- select(old_data、最初の変数、2 番目の変数)

変数はいくつでも選択できることに注意してください。

次に、必要なタイプのデータを取得します。

どうもありがとう、

ファダ

于 2016-03-03T23:34:19.200 に答える