【问题标题】:Create new variable in data table based on conditions on other variables根据其他变量的条件在数据表中创建新变量
【发布时间】:2015-02-21 00:01:09
【问题描述】:

我想在数据表中创建一个新变量,其值取决于数据表中其他变量的关系。假设我有一个包含三个变量的数据表:

library(data.table)
DT <- data.table(replicate(3,sample(0:2,5,replace=TRUE)))
DT
   V1 V2 V3
1:  0  2  1
2:  1  2  1
3:  2  0  1
4:  1  1  0
5:  1  0  0

我想创建一个基于以下函数的新变量:

myfun <- function(a,b,c) {
  newvar = "x"
  if (a > b + c) {
    newvar = "a"
  }
  if (b > a + c) {
    newvar = "b"
  }
  if (c > a + b) {
    newvar = "c"
  }
  return(newvar)
}

我尝试应用与加法等相同的逻辑,但在这里失败了。

DT[, new_var := myfun(V1, V2, V3)]

这应该与向量的加法和比较的不同性质有关。解决这个问题的正确方法是什么?

【问题讨论】:

  • 我猜它不起作用,因为 if 运算符未矢量化。相反,您可以使用ifelse
  • @janosdivenyi 另一个使用combnindx &lt;- DT&gt;DT[,3:1, with=FALSE][, combn(.SD, 2, FUN=function(x) x[[1]]+x[[2]])]; DT[, newcol:=c('x', letters[1:3])[as.vector(indx%*%seq_len(ncol(indx)))+1]]的选项

标签: r comparison data.table


【解决方案1】:

你的条件可以改写为

bigcol <- apply(2*DT > rowSums(DT),1,which)

因为 a > b+c 等价于 2a > a+b+c,以此类推。您的新专栏是

DT[,newcol:=
  sapply(bigcol,function(x) if(length(x)==0) 'x' else letters[x])
]

如果您将使用矩阵来存储数据,那么矩阵可能是最自然的存储方式。这里的方法在计算上可能会更简单一些:

mat <- as.matrix(DT)
maxxer <- apply(mat,1,which.max)
newcol <- ifelse(
  2*mat[cbind(1:nrow(mat),maxxer)] > rowSums(mat),
  letters[maxxer],
  'x'
)

只有最大的列是替换 x 的竞争者,所以我们可以将它与总和进行比较。

【讨论】:

  • 不幸的是,我的问题涉及更复杂的条件:(a + b + c &gt; 0 & a &gt; 2*b) 标识一个组 (a + b + c &gt; 0 & b &gt; 2*a) 标识另一个组,(a + b + c &gt; 0 但都不是a &gt; 2*b也不是b &gt; 2*a) 标识另一个,a + b + c = 0 标识最后一个。我看不到任何简单的方法来重写它。
  • 嗯,也许这值得它自己的问题......?我以为您的意思是您实际上使用的是上面的函数,而不是 like 上面的函数。
  • 然而,这又有一个简单的形式:定义比率abrat &lt;- a/b;然后使用ifelse(a+b+c==0,'z',letters[1:3][findInterval(abrat,c(0,.5,2))]) 或类似的东西。
  • a = b = 0c &gt; 0 以及a &gt; 0b = 0(因此,a/b 未定义)时,您仍然需要处理这种情况,但感谢您的想法。
  • @janosdivenyi 哦,对。我认为插入一对支票会起作用,例如ifelse(a+b+c==0,'z',ifelse(b==0,ifelse(a==0,'c','a'),letters[1:3][findInterval(abrat,c(0,.5,2))]))。不过,这可能比更直接的ifelse(a+b+c==0,'z',ifelse(a&gt;2*b,'a',ifelse(b&gt;2*a,'b','c'))) 好一点。
猜你喜欢
  • 2018-07-02
  • 2022-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-28
  • 1970-01-01
相关资源
最近更新 更多