2013-05-12 1 views
5

У меня есть этот код:Вновь добавленный столбец в «у» из data.table должен быть доступен в рамках

dat<-dat[,list(colA,colB 
        ,RelativeIncome=Income/.SD[Nation=="America",Income] 
        ,RelativeIncomeLog2=log2(Income)-log2(.SD[Nation=="America",Income])) #Read 1) 
       ,by=list(Name,Nation)] 

1) Я хотел бы быть в состоянии сказать "RelativeIncomeLog2=log2(RelativeIncome)", но "RelativeIncome" не доступна в j 's scope?

2) Я попробовал следующее вместо этого (в FAQ). Теперь "RelativeIncome" доступен, но он не добавляет столбцы:

 dat<-dat[,{colA;colB;RelativeIncome=Income/.SD[Nation=="America",Income]; 
       ,RelativeIncomeLog2=log2(RelativeIncome)])) 
       ,by=list(Name,Nation)] 
+1

Ответ Рикардо, вероятно, разъясняет это, но функция 'J()' не совпадает с аргументом 'j' для' [.data.table'. Попробуйте ''? J'' и '' '' [.data.table' '' для деталей. 'J()' для объединений в аргументе 'i'' [.data.table'. – Frank

+0

См. Также [Как я могу оценить (или создать) столбец «на лету» в data.table в r] (https://stackoverflow.com/questions/15712858/how-can-i-evaluate-or-create-an -on-the-fly-column-in-data-table-in-r) – Henrik

ответ

8

Вы можете создавать и назначать объекты в j, просто используйте { фигурные скобки }.

Вы можете передать эти объекты (или функции & вычисления объектов) из j и назначить их как столбцы таблицы данных. Для того, чтобы назначить более одного раза колонки в то время, просто:

  • обернуть LHS в c(.)убедитесь, что имена столбцов являются строками и
  • последняя линия j (то есть «возврат» значение) должен быть списком.

dat[ , c("NewIncomeComlumn", "AnotherNewColumn") := { 
       RelativeIncome  <- Income/.SD[Nation == "A", Income]; 
       RelativeIncomeLog2 <- log2(RelativeIncome); 
       ## this last line is what will be asigned. 
       list(RelativeIncomeLog2 * 100, c("A", "hello", "World")) 
       # assigned values are recycled as needed. 
       # If the recycling does not match up, a warning is issued. 
       } 
       , by = list(Name, Nation) 
       ] 

Вы можете losely думать j как функции в среде dat

Вы также можете получить намного более изощренными и сложными, если это необходимо. Вы можете также включить by аргументы, а также, используя by=list(<someName>=col)

На самом деле, подобные функции, просто создавая объект в j и присвоив ей значение, не означает, что она будет доступна за пределами j. Чтобы он был присвоен вашей таблице данных., Вы должны вернуть его. j автоматически возвращает последнюю строку; если эта последняя строка является списком, каждый элемент списка будет обрабатываться как столбец. Если вы назначаете по ссылке (т. Е. Используя :=), то вы достигнете ожидаемых результатов.


На отдельной ноте, я заметил, что в вашем коде:

Income/.SD[Nation == "America", Income] 

# Which instead could simply be: 
Income/Income[Nation == "America"] 

.SD велика, что она является прекрасным стенографии. Однако для его вызова без необходимости использования всех столбцов, которые он инкапсулирует, необходимо обременять ваш код дополнительными расходами на память. Если вы используете только один столбец, подумайте об именовании этого столбца в явном виде или, возможно, добавьте аргумент .SDcols (после j) и указав нужные столбцы.

+0

может быть глупый вопрос .. но что в вашем примере только «RelativeIncomeLog2 * 100» будет присвоено значение NewIncomeColumn. Но что, если я хочу 2 новых столбца, соответствующих «RelativeIncome» и «RelativeIncomeLog2 * 100»? – varuman

+0

@varuman, не глупый вопрос. Короткий ответ заключается в том, чтобы обернуть окончательную строку в 'list (.)' См. Приведенное выше изменение для получения более подробной информации. –

+0

@RicardoSaporta, я думаю, что ошибка 'by = ...' в конце '}'? Разве это не должно произойти после инструкции 'list (.)'? – Arun

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