如何根据data.table中的其他列创建新列?

时间:2015-11-17 23:11:21

标签: r data.table

DT0 = data.table(x=rep(c(NA,NA,NA)), y=c(0,1,NA), v=c(0, 0, NA), l=c(1,1,1))
DT0
#    x  y  v l
#1: NA  0  0 1
#2: NA  1  0 1
#3: NA NA NA 1

基于前三个列xyv我想添加一个新的col以及以下输出

#1:  No
#2: Yes
#3:  NA
如果所有行都是NA,则

NAYes 1如果其中任何一个是0其他relevant_cols <- c('x', 'y', 'v') new <- data.table(apply(DT0[, relevant_cols, with=F], 1, function(val) { ifelse(all(is.na(val)), NA_character_, ifelse(any(val == TRUE, na.rm = TRUE), 'Yes', 'No')) })) DT0[, new:= new] DT0 # x y v l new #1: NA 0 0 1 No #2: NA 1 0 1 Yes #3: NA NA NA 1 NA 。我目前的做法是

data.table

但是,由于实际的pmax很大,有没有更好的方法呢?

修改 通常data.table条目是非数字的,因此如果我可以使用比使用e.g. DT = data.table(x=rep(c(NA,NA,NA)), y=c('No','Yes',NA), v=c('No', 'No', NA), l=c(1,1,1)) DT # x y v l #1: NA No No 1 #2: NA Yes No 1 #3: NA NA NA 1 更通用的解决方案,那将非常有用,

LIBPROCESS_IP

2 个答案:

答案 0 :(得分:1)

这是一个选项:

DT[, new := ifelse(rowSums(.SD == "Yes", na.rm = T) > 0,
                   'Yes',
                   ifelse(rowSums(is.na(.SD)) != ncol(.SD), "No", NA))
   , .SDcols = x:v]
#    x   y  v l new
#1: NA  No No 1  No
#2: NA Yes No 1 Yes
#3: NA  NA NA 1  NA

答案 1 :(得分:0)

pmax非常适合这个问题。

第一个例子在0/1情况下......

DT0[, do.call(pmax, c(na.rm=TRUE, .SD)), .SDcols=x:v]
# 0 1 NA

第二个例子如果您将0/1编码为my_lvls = c("No","Yes")而不是......

DT[, 
  factor(
    labels = my_lvls,
    x      = do.call(pmax, c(na.rm=TRUE, lapply(.SD, function(x) 
               as.integer(factor(x, levels=my_lvls)))))
  )
, .SDcols=x:v]
# [1] No   Yes  <NA>
# Levels: No Yes

如@ eddi的回答所示,要添加新列,您可以将x:v放入.SDcols并使用.SD