r-if-else命令在data.table中添加列



假设我有一个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")]

最新更新