Функция data.table применяется к каждому столбцу - PullRequest
0 голосов
/ 28 августа 2018

Я думаю, я довольно близок к решению, но я изо всех сил пытаюсь совместить lapply с data.table. Я много читаю о lapply и нахожу пример с data.table, но способ мышления для меня нов, и он сводит меня с ума ...

Это мой 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)))

но это чепуха.

Спасибо Alina

1 Ответ

0 голосов
/ 28 августа 2018

Похоже, вы устанавливаете столбцы лет с 1, если он находится между begy и begy + SeqLen - 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)))] 
...