2013-09-18 6 views
19

Я работаю с чрезвычайно большим набором данных в R и работал с кадрами данных и решил переключиться на data.tables, чтобы ускорить работу. У меня возникли проблемы с пониманием операций J, в частности, я пытаюсь создать фиктивные переменные, но я не могу понять, как закодировать условные операции в data.tables [].Создание фиктивных переменных в R data.table

MWE:

test <- data.table("index"=rep(letters[1:10],100),"var1"=rnorm(1000,0,1)) 

То, что я хотел бы сделать, это добавить столбцы a через j как фиктивные переменные, такие, что столбец a будет иметь значение 1 когда index == "a" и 0 иначе. В среде data.frame это будет выглядеть примерно так:

test$a <- 0 

test$a[test$index=='a'] <- 1 
+0

Вот пример с манекенами, которые могут помочь: http://stackoverflow.com/questions/18871614/r-datatable-join-and-constrain-rows/18874811#18874811 – Frank

+2

Что такое «очень большой»? Является ли 'model.matrix (~ var1 + index-1, test)' слишком медленным? – Roland

+1

С моим набором данных (9 миллионов строк) решение Фрэнка ниже - это единственное, что работает. С 'model.matrix' у меня заканчивается память. – Riccardo

ответ

25

Это, кажется, делать то, что вы ищете:

inds <- unique(test$index) 
test[, (inds) := lapply(inds, function(x) index == x)] 

, который дает

 index  var1  a  b  c  d  e  f  g  h  i  j 
    1:  a 0.25331851 TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
    2:  b -0.02854676 FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
    3:  c -0.04287046 FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
    4:  d 1.36860228 FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE 
    5:  e -0.22577099 FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE 
    ---                    
996:  f -1.02040059 FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE 
997:  g -1.31345092 FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE 
998:  h -0.49448088 FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE 
999:  i 1.75175715 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE 
1000:  j 0.05576477 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE 

Вот еще один способ:

dcast(test, index + var1 ~ index, fun = length) 
# or, if you want to preserve row order 
dcast(test[, r := .I], r + index + var1 ~ index, fun = length)[, r := NULL] 

И еще:

rs = split(seq(nrow(test)), test$index) 
test[, names(rs) := FALSE ] 
for (n in names(rs)) set(test, i = rs[[n]], j = n, v = TRUE) 
+0

Фрэнк, есть ли способ сделать это гибким, чтобы вы могли создавать несколько манекенов на нескольких столбцах? В принципе, что, если у вас нет столбца с индексом, но вы хотите вызвать конкретный номер столбца в функции lapply, а затем поместить вокруг него цикл, чтобы он мог выполнить это для нескольких столбцов? – SJDS

+0

@simon_icl Да, цикл должен работать. Если вы не знаете, как это сделать, опубликуйте его как вопрос, и я могу показать, как я это сделаю (и у кого-то может быть лучший/более эффективный подход). Завтра я посмотрю. – Frank

+0

Связанный (вопрос Саймона): http://stackoverflow.com/q/28576729/1191259 – Frank

Смежные вопросы