使用`:=`和双索引创建data.table列

时间:2014-11-15 19:32:45

标签: r data.table

我正在处理一个data.table实例并希望使用:=创建一个额外的列,这个工作正常,直到我做了一些双重索引。

对于data.table的以下实例:

example_data= structure(list(V1 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,1L, 1L), 
                             .Label = c("AUDUSD", "EURUSD", "GBPUSD", "NZDUSD", "USDCAD","USDJPY"), class = "factor"), 
                             V2 = structure(c(1L, 1L, 1L, 1L,1L, 1L, 1L, 1L, 1L, 1L), 
                              .Label = c("2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014"), 
                             class = "factor"), 
                             V3 = c("1.RData", "10.RData", "11.RData", "12.RData", "2.RData", "3.RData", "4.RData", "5.RData", "6.RData", "7.RData")), 
                        .Names = c("V1", "V2", "V3"), 
                        class = c("data.table", "data.frame"), row.names = c(NA, -10L))

给出了这个数据:

example_data V1 V2 V3 1: AUDUSD 2007 1.RData 2: AUDUSD 2007 10.RData 3: AUDUSD 2007 11.RData 4: AUDUSD 2007 12.RData 5: AUDUSD 2007 2.RData 6: AUDUSD 2007 3.RData 7: AUDUSD 2007 4.RData 8: AUDUSD 2007 5.RData 9: AUDUSD 2007 6.RData 10: AUDUSD 2007 7.RData

我希望将“V3”列拆分为“。”并将前面的数字作为同一个表中新列中的字符。

在正常的R:

中这样做很简单

example_data$MONTH = apply(example_data,1, function(x) { strsplit(as.character(x[["V3"]]),"\\.")[[1]][1]})

我认为在data.table中这样做会更加直截了当:

example_data[,MONTH:=strsplit(as.character(V3),"\\.")[[1]][1]]

然而,双重索引没有按我的意图解释,因为它正在将所有值更改为第一行的结果。删除索引确实执行了正确的操作(只是没有提取并将数据放在正确的位置):

example_data[,strsplit(as.character(V3),"\\.")]

我还尝试通过应用函数内化索引,但得到了相同的错误结果:

myfunc <- function(x) { strsplit(as.character(x),"\\.")[[1]][1] } example_data[,MONTH:=myfunc(V3)]

我总是可以使用标准的R解决方案,但是如果有人知道基于data.table的解决方案,我们将不胜感激。我对其他标准R或基于(d)plyr的替代品不感兴趣(它们很棒 - 只是不是我要问的)。

2 个答案:

答案 0 :(得分:3)

您应该使用sub代替strsplit

example_data[ , MONTH := sub("\\..*", "", V3)]

        V1   V2       V3 MONTH
 1: AUDUSD 2007  1.RData     1
 2: AUDUSD 2007 10.RData    10
 3: AUDUSD 2007 11.RData    11
 4: AUDUSD 2007 12.RData    12
 5: AUDUSD 2007  2.RData     2
 6: AUDUSD 2007  3.RData     3
 7: AUDUSD 2007  4.RData     4
 8: AUDUSD 2007  5.RData     5
 9: AUDUSD 2007  6.RData     6
10: AUDUSD 2007  7.RData     7

但是,它也适用于strsplit

example_data[ , MONTH := unlist(strsplit(V3, "\\..*"))]

答案 1 :(得分:1)

data.table v1.9.5 中推送了两个函数transpose()tstrsplit()

我们可以这样做:

require(data.table)
setDT(example_data)[, col := tstrsplit(V3, ".", fixed=TRUE)[[1L]]]
#         V1   V2       V3 col
#  1: AUDUSD 2007  1.RData   1
#  2: AUDUSD 2007 10.RData  10
#  3: AUDUSD 2007 11.RData  11
#  4: AUDUSD 2007 12.RData  12
#  5: AUDUSD 2007  2.RData   2
#  6: AUDUSD 2007  3.RData   3
#  7: AUDUSD 2007  4.RData   4
#  8: AUDUSD 2007  5.RData   5
#  9: AUDUSD 2007  6.RData   6
# 10: AUDUSD 2007  7.RData   7

tstrsplittranspose(strsplit(...))的包装器。 transpose()也可用于列表数据框数据表。请查看文档和示例以获取更多信息。