假设我有一个data.table;A"C"byvar";有时;B";。我想用变量"byvar"来概括它,但只包括B,如果它存在或以其他条件为条件。
以下内容似乎不起作用,有人有想法吗?
dt[, .(
A=sum(A),
if("B" %in% names(dt)) {B=mean(B)},
C=mean(C),
D=sum(A)/C
), by = .(byvar)]
试试B=ifelse("B"%in%names(dt),mean(B),NA)
,它会给你一个带有NA的列,但它可以扩展到任意条件和列名。
dt<-data.table(A=runif(100,1,100), C=runif(100,1,100), byvar=rep(letters[1:10],10))
dt[, .(
A=sum(A),
B=ifelse("B"%in%names(dt),mean(B),NA),
C=mean(C),
D=sum(A)/C
), by = .(byvar)]
在运行这个过程中,我得到了100行响应,因为你的D=sum(A)/C
中有C
,它获取了原始的C,而不是新的C,所以它给了你100行,因为有100个C
。如果你把D
的定义改为sum(A)/mean(C)
,那么它就给出了你可能想要的。
编辑:
另一种方法是利用在J
表达式中使用大括号的能力
dt[, {checkcol='B'
prelimreturn=list(A=sum(A),
C=mean(C),
D=sum(A)/mean(C))
if(checkcol%in%names(dt)) prelimreturn[[checkcol]]<-mean(get(checkcol))
prelimreturn}
, by = .(byvar)]
在这里,我设置了一个名为checkcol
的辅助变量,这样我们就不会把"B"
放在两个地方。接下来,我们用你知道你想要的列来做你的初步结果。之后,我们检查checkcol
中是否存在任何内容,如果存在,我们将该列添加到现有列表中。大括号中的最后一行是CCD_ 11显示的内容,它是我们的CCD_;B";柱你也可以将这种方法扩展得相当广泛。
您可以尝试
dt[, lapply(.SD, sum), byvar,,.SDcols = patterns("A|B|C")]