Если вам нужны только четыре позиции в этом списке, вы должны просто пластинчатый:
indcols <- paste0('index',1:3)
lapply(new[,indcols,with=FALSE],table) # counts
lapply(new[,indcols,with=FALSE],function(x)prop.table(table(x))) # means
# or...
lapply(
new[,indcols,with=FALSE],
function(x){
z<-table(x)
rbind(count=z,mean=prop.table(z))
})
Это дает
$index1
a b c d e
count 200.0 200.0 200.0 200.0 200.0
mean 0.2 0.2 0.2 0.2 0.2
$index2
f g h i j k l m n o
count 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0 100.0
mean 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1
$index3
p q r s
count 250.00 250.00 250.00 250.00
mean 0.25 0.25 0.25 0.25
Предыдущий подход будет работать на data.frame или data.table, но довольно сложный. С data.table, можно использовать melt
синтаксис:
melt(new, id="id")[,.(
N=.N,
mean=.N/nrow(new)
), by=.(variable,value)]
, который дает
variable value N mean
1: index1 a 200 0.20
2: index1 b 200 0.20
3: index1 c 200 0.20
4: index1 d 200 0.20
5: index1 e 200 0.20
6: index2 f 100 0.10
7: index2 g 100 0.10
8: index2 h 100 0.10
9: index2 i 100 0.10
10: index2 j 100 0.10
11: index2 k 100 0.10
12: index2 l 100 0.10
13: index2 m 100 0.10
14: index2 n 100 0.10
15: index2 o 100 0.10
16: index3 p 250 0.25
17: index3 q 250 0.25
18: index3 r 250 0.25
19: index3 s 250 0.25
Этот подход был упомянут @Arun в комментарии (и осуществляется его также, я думаю .. ?). Чтобы увидеть, как это работает, сначала взгляните на melt(new, id="id")
, который преобразует исходную таблицу данных.
Как указано в комментариях, для плавления таблицы данных необходимо установить и загрузить reshape2
для некоторых версий пакета data.table
.
Если вы нужны манекены, они могут быть выполнены в виде петли, как в связанном вопрос:
newcols <- list()
for (i in indcols){
vals = unique(new[[i]])
newcols[[i]] = paste(vals,i,sep='_')
new[,(newcols[[i]]):=lapply(vals,function(x)get(i)==x)]
}
Это хранит группы столбцов, связанных с каждой переменной в newcols
для удобство.Если вы хотите, чтобы сделать табуляцию только с этими манекенами (вместо основных переменных, как в растворе выше), вы могли бы сделать
lapply(
indcols,
function(i) new[,lapply(.SD,function(x){
z <- sum(x)
list(z,z/.N)
}),.SDcols=newcols[[i]] ])
, который дает аналогичный результат. Я просто написал это так, чтобы проиллюстрировать, как можно использовать синтаксис data.table
. Можно снова избежать квадратные скобки и .SD
здесь:
lapply(
indcols,
function(i) sapply(
new[, newcols[[i]], with=FALSE],
function(x){
z<-sum(x)
rbind(z,z/length(x))
}))
Но в любом случае: просто использовать table
, если вы можете держать на основных переменных.
Не было бы легче, если бы мы * расплавились * это? то есть для первых двух частей «расплавить (новый, id =« id ») [,. (N = .N, mean = .N/nrow (new)), by =. (variable, value)]'. Добавьте 'id' к переменной группировки для последних 2 ..? – Arun
@ Арун: Возможно. Я еще не знаком с синтаксисом «расплав». Я бы попробовал, но 'melt' и' melt.data.table' говорят: «Не удалось найти функцию» (даже если 'help (melt.data.table)' работает). Я предполагаю, что моя установка пакета не обновлено для этого еще ...? В любом случае, я думаю, вы бы лучше позиционировались, чтобы ответить с этим синтаксисом. Не стесняйтесь редактировать или добавлять другой ответ. Мне интересно посмотреть, как это работает. – Frank
Версии <1.9.4 требует ' reshape2' для загрузки, вам это не нужно от '1.9.5 +'. – Arun