2017-01-20 3 views
0

複数の列を持つデータテーブルがあります。次のように同一の短い再現例は:複数の関数を使用してデータテーブルを集計するときに列名を取得するR

library(data.table) 
DT = setDT(structure(list(ZONE = c("WEST", "WEST", "WEST", "EAST", "EAST", 
"EAST", "EAST"), PULSES = c(347, 70, 110, 720, 280, 190, 35), 
    FRUITS = c(172, 130, 0, 578, 350, 220, 50), CEREALS = c(740, 
    639, 149, 1381, 2415, 1765, 525), newmlt = c(8248, 838.5, 
    287.75, 46, 60.375, 38.81, 38.81)), .Names = c("ZONE", "PULSES", 
"FRUITS", "CEREALS", "newmlt"), row.names = c(NA, -7L), class = c("data.table", 
"data.frame"))) 

Iが同じ列に異なる機能を適用することによって、複数のサマリを生成するデータ・フレームの複数の列(動的変更)を要約しようとしています。たとえば:

機能非ゼロ

usrs <- function(x) round(length(x[x != 0])/length(x)*100,0) 

の%にsummarisation

の列を選択する平均

my.summary = function(x) list(MEAN = mean(x), 'USERS_%' = usrs(x)) 

とそれを包む:次は、機能の一部です

cols <- c('PULSES', 'CEREALS') 

data.tableを使用

cerr <- DT[, unlist(lapply(.SD, my.summary)), .SDcols = cols, by = ZONE] 
cerr 

グループ別オプションも動的に変更されます。 しかし、私は上記のコードを使用して列名を取得していません。どのようにしてゾーン名とV1とともに列名を取得するのですか?

私もsetkey(DT, ZONE)を試して、by = .EACHIを使用しましたが、私のusrs機能ではNAを取得しました。次のように

私の所望の出力は次のようになります。

ZONE  COL   V1 
1: WEST MEAN.PULSES 175.6667 
2: WEST usrs.PULSES 100.0000 
3: WEST MEAN.CEREALS 509.3333 
4: WEST usrs.CEREALS 100.0000 
5: EAST MEAN.PULSES 306.2500 
6: EAST usrs.PULSES 100.0000 
7: EAST MEAN.CEREALS 1521.5000 
8: EAST usrs.CEREALS 100.0000 

私はあまりにも出力の列の一つとして、列名を取得するにはどうすればよいです。

+1

'のDF' – MichaelChirico

+2


代わりに、あなたはすべてのcols、その後フィルタのためにそれを計算することができ私は、溶融(DT [、c( "ZONE"、cols)、= FALSE]、id = "ZONE")[、m = mean(value)、nz = round(mean(value! 0)* 100,0))、by =。(ZONE、variable)] '(別の列に統計情報を残しておきます。 – Frank

+0

@Frank多くのありがとう...完璧に私のユースケースに合っています....私は答えとしてこれを受け入れることができます。 – Apricot

答えて

2

あなたは再び別々の列、meltに積層代わりのデータが必要な場合、私は

cols <- c('PULSES', 'CEREALS') 
melt(DT[, c("ZONE", cols), with=FALSE], id="ZONE")[, 
    .(m = mean(value), nz = round(mean(value!=0)*100, 0)) 
, by=.(ZONE,variable)] 

# ZONE variable   m nz 
# 1: WEST PULSES 175.6667 100 
# 2: EAST PULSES 306.2500 100 
# 3: WEST CEREALS 509.3333 100 
# 4: EAST CEREALS 1521.5000 100 

をお勧めしたいです。 [(lapplyリスト(COLS)、(.SD、my.summary))、C]

cols <- c('PULSES', 'CEREALS') 
melt(DT, id="ZONE")[, 
    .(m = mean(value), nz = round(mean(value!=0)*100,0)) 
, by=.(ZONE,variable)][ variable %in% cols ] 
関連する問題