如何在data.table中的每一行中应用函数

时间:2015-10-19 09:04:38

标签: r data.table

假设我有以下

dt <- data.table(a=c(T,T,F,F), b= c(T,F,T,F))

返回,

       a     b
1:  TRUE  TRUE
2:  TRUE FALSE
3: FALSE  TRUE
4: FALSE FALSE

我尝试使用function(x) min(which(x))来确定TRUE中每行的第一个dt,但它不起作用。我期望的结果将是

       a     b index
1:  TRUE  TRUE     1
2:  TRUE FALSE     1
3: FALSE  TRUE     2
4: FALSE FALSE  9999

,其中索引列表示第一个TRUE的位置,当该行仅包含FALSE时使用9999

仅供参考:在实际数据中,我有大约50个包含TRUE和FALSE的列

你能给我一些建议吗?

3 个答案:

答案 0 :(得分:4)

对于50列,最好使用max.col

dt$index <- max.col(dt, 'first') *(!!rowSums(dt))

或者@David Arenburg提到,更多的惯用代码将是

dt[, indx := max.col(.SD,ties.method="first")*(!!rowSums(.SD))]

如果我们需要9999

 (max.col(dt)*(!!rowSums(dt))) + (!rowSums(dt))*9999

答案 1 :(得分:2)

有点晚但这是一种方式:

#initial data.table - added a row id
dt <- data.table(a=c(T,T,F,F), b= c(T,F,T,F))[, id := .I]

#if the row sums equal 0 then 9999 else pick the first max i.e. the first TRUE
dt[, index := if(rowSums(.SD)==0) 9999 else as.double(which.max(.SD)), by=id]

或者根据@David的评论,为了避免矩阵转换:

dt[, index := if(Reduce('+', .SD)==0) 9999 else as.double(which.max(.SD)), by=id]

输出:

> dt
       a     b id index
1:  TRUE  TRUE  1     1
2:  TRUE FALSE  2     1
3: FALSE  TRUE  3     2
4: FALSE FALSE  4  9999

答案 2 :(得分:2)

另外,

ans = rep_len(9999L, nrow(dt))
for(i in length(dt):1L) ans[dt[[i]]] = i
ans
#[1]    1    1    2 9999