6

我有这个代码:

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 范围内?

2)我尝试了以下方法(根据 data.table FAQ)。现在"RelativeIncome"可用,但它不添加列:

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

1 回答 1

9

您可以在 中创建和分配对象j,只需使用{花括号}

然后,您可以将这些对象(或对象的函数和计算)传递出去,j并将它们分配为 data.table 的列。要一次分配多个列,只需:

  • 包装LHSc(.) 确保列名是字符串
  • 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)
               ]

你可以迷失地认为是j环境中的一个功能dat

如果需要,您还可以变得更加复杂和复杂。您也可以合并by参数,使用 by=list(<someName>=col)

事实上,类似于函数,只是在其中创建一个对象j并为其赋值,并不意味着它在j. 为了将其分配给您的 data.table,您必须返回它。 j自动返回最后一行;如果最后一行是一个列表,则列表的每个元素都将作为一列处理。如果您通过引用(即使用:=)进行分配,那么您将获得您期望的结果。


另外,我在您的代码中注意到以下内容:

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

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

.SD很棒,因为它是一个很棒的速记。但是,在不需要它封装的所有列的情况下调用它会给您的代码带来额外的内存成本。如果您只使用单个列,请考虑显式命名该列,或者添加.SDcols参数(在 之后j)并在那里命名所需的列。

于 2013-05-12T19:36:53.847 回答