Мы преобразуем «data.frame» в «data.table» и создаем столбец идентификатора строки (setDT(df1, keep.rownames=TRUE)
). Мы переформатируем формат «широкий» в «длинный» с помощью melt
. В группе «rn», if
нет элемента NA
в столбце «значение», мы получаем последний элемент «value» (value[.N]
) или else
, мы получаем элемент перед первым NA в «значение», чтобы получить столбец «V1», который мы извлекаем ($V1
).
melt(setDT(df1, keep.rownames=TRUE), id.var='rn')[,
if(!any(is.na(value))) value[.N]
else value[which(is.na(value))[1]-1], by = rn]$V1
#[1] "u" "q" "w" "h" "r" "t" "e" "t"
В случае, если данные уже являются data.table
dat[, rn := 1:.N]#create the 'rn' column
melt(dat, id.var='rn')[, #melt from wide to long format
if(!any(is.na(value))) value[.N]
else value[which(is.na(value))[1]-1], by = rn]$V1
#[1] "u" "q" "w" "h" "r" "t" "e" "t"
Вот еще один вариант
dat[, colInd := sum(!is.na(.SD)), by=1:nrow(dat)][
, as.character(.SD[[.BY[[1]]]]), by=colInd]
Или как @Frank, упомянутый в комментариях, мы можем использовать na.rm=TRUE
из melt
и сделать его более компактным
melt(dat[, r := .I], id="r", na.rm=TRUE)[, value[.N], by=r]