当使用.SD
将函数应用于dt
列的子集时,我似乎找不到正确的方法来处理我有重复列名的情况......例如
# Make some data
set.seed(123)
dt <- data.table( matrix( sample(6,16,repl=T) , 4 ) )
setnames(dt , rep( letters[1:2] , 2 ) )
# a b a b
#1: 2 6 4 5
#2: 5 1 3 4
#3: 3 4 6 1
#4: 6 6 3 6
# Use .SDcols to multiply both column 'a' specifying them by numeric position
dt[ , lapply( .SD , `*` , 2 ) , .SDcols = which( names(dt) %in% "a" ) ]
# a a
#1: 4 4
#2: 10 10
#3: 6 6
#4: 12 12
当.SDcols
是列名的字符向量时,我无法使用它,所以我尝试了数字位置(which( names(dt) %in% "a" )
给出了一个向量[1] 1 3
)但它似乎也只需将第一个a
列相乘即可。我做错了吗?
.SDcols
高级。指定.SD中包含的x列。可以是字符列名称或数字位置。
这些也返回了与上面相同的结果......
dt[ , lapply( .SD ,function(x) x*2 ) , .SDcols = which( names(dt) %in% "a" ) ]
dt[ , lapply( .SD ,function(x) x*2 ) , .SDcols = c(1,3) ]
packageVersion("data.table")
#[1] ‘1.8.11’
答案 0 :(得分:1)
这个怎么样
dt[, (names(dt) %in% "a"), with = FALSE] * 2
## a a.1
## 1 4 8
## 2 10 6
## 3 6 12
## 4 12 6
有关更详细的讨论
http://chat.stackoverflow.com/transcript/message/12783493#12783493
答案 1 :(得分:1)
data.tables
上具有重复列的一致子集规则。简而言之,如果直接提供索引,&#39; j,或.SDcols
,则只返回这些列(如果您提供 -.SDcols
或{{1},则删除这些列})。相反,如果给出列名并且该列出现多次,那么很难确定要保留哪个以及要在子集上删除哪个。因此,要删除,删除该列的所有实例,并且要保留,每次都返回第一列。同时关闭#5688和#5008。请注意,使用!j
在重复列上进行聚合可能无法提供预期结果,因为它可能无法在正确的列上运行。
基本上,如果你这样做:
by=
它仍然会给出意想不到的结果,因为很难分辨哪个&#34; a&#34;你每次都提到 - 所以总是选择第一个。
但如果您明确指定(如您在Q中所做的那样):
dt[, lapply(.SD, `*`, 2), .SDcols=c("a", "a")]
# a a
# 1: 4 4
# 2: 10 10
# 3: 6 6
# 4: 12 12