我想我已经很接近解决方案了,但是我很难将lapply与data.table结合起来。我阅读了很多有关lapply的内容,并找到了有关data.table的示例,但是这种思维方式对我来说是新的,它使我发疯...
这是我的数据表。
cells <- c(150, 1,1980,1,1,1,0,0,0,1,2004,3,
99 , 1,1980,1,1,1,1,0,0,0,2004,4,
899, 1,1980,0,1,0,1,1,1,1,2007,4,
789, 1,1982,1,1,1,0,1,1,1,2004,3 )
colname <- c("number","sex", "birthy", "2004","2005", "2006", "2007", "2008", "2009","2010","begy","SeqLen")
rowname <- c("2","3","4","5")
y <- matrix(cells, nrow=4, ncol=12, byrow=TRUE, dimnames = list(rowname,colname))
y <- data.table(y, keep.rownames = TRUE)
我想逐步浏览列名的向量
cols <- c(paste(2004:2010, sep=" "))
仅对一列执行以下操作即可!
vec <- "2005"
y[, (vec) := ifelse((vec) < as.numeric(begy),0, ifelse( ((vec) > as.numeric(begy) + as.numeric(SeqLen) -1) ,0,1)) ]
创建一个函数并逐步遍历向量接缝是一个很好的解决方案,但是如何呢? 我找到了...
dt[ , (cols) := lapply(.SD, "*", -1), .SDcols = cols]
但是在这个示例中我可以将ifelse放在哪里?
我还读到了有关for循环和set函数的信息,
for (j in cols) set(dt, j = j, value = ifelse((dt[[j]]) < as.numeric(dt[[begy]]),0, ifelse( (dt[[j]] > as.numeric(dt[[begy]]) + as.numeric(dt[[SeqLen]]) -1) ,0,1)))
但这是废话。
谢谢 阿丽娜
答案 0 :(得分:1)
如果每一行的年份列在begy
和begy + SeqLen - 1
之间,则好像您将年份列设置为1。这是执行此操作的另一种方法:
y[order(rn),
(grep("^20", names(y), value=TRUE)) :=
dcast(y[, seq(begy, by=1, length.out=SeqLen), by=.(rn)], rn ~ V1, length)[,-1L]]
y
输出:
rn number sex birthy 2004 2005 2006 2007 2008 2009 2010 begy SeqLen
1: 2 150 1 1980 1 1 1 0 0 0 0 2004 3
2: 3 99 1 1980 1 1 1 1 0 0 0 2004 4
3: 4 899 1 1980 0 0 0 1 1 1 1 2007 4
4: 5 789 1 1982 1 1 1 0 0 0 0 2004 3
说明:
为每一行创建一个年份序列,然后使用dcast
进行一次热编码。使用输出覆盖年份列。
order(rn)
将确保我们不会在dcast
之后错误地覆盖行
弗兰克的方法更快:
y[, as.character(2004:2010) :=
lapply(2004:2010, function(x) as.integer(between(x, begy, begy + SeqLen - 1)))]