Извлекать и сворачивать неотсутствующие элементы по строкам в таблице data.table - PullRequest
1 голос
/ 28 мая 2020

Я хотел бы извлечь все уникальные не отсутствующие элементы в строке, а затем свернуть их, используя &&&&. Вот небольшой пример:

#Load needed libraries:
library(data.table)

#Generate the data:
set.seed(1)
n_rows<-10

#Define function to apply to rows:
function_non_missing<-function(x){
  x<-x[!is.na(x)]
  x<-x[x!="NA"]
  x<-unique(x[order(x)])
  paste(x,collapse="&&&&")
}

data<-data.table(
  a=sample(c(1,2,NA,NA),n_rows,replace=TRUE),
  b=sample(c(1,2,NA,NA),n_rows,replace=TRUE),
  c=sample(c(1,2,NA,NA),n_rows,replace=TRUE)
)

> data
     a  b  c
 1:  1 NA  1
 2: NA NA NA
 3: NA  1  1
 4:  1  1  1
 5:  2  1  1
 6:  1  2  1
 7: NA  2  2
 8: NA  2  1
 9:  2  2  1
10:  2 NA  2

#Obtain results
data[,paste(.SD),by=1:nrow(data)][,function_non_missing(V1),by=nrow]

    nrow     V1
 1:    1      1
 2:    2       
 3:    3      1
 4:    4      1
 5:    5 1&&&&2
 6:    6 1&&&&2
 7:    7      2
 8:    8 1&&&&2
 9:    9 1&&&&2
10:   10      2

Приведенный выше код выглядит очень запутанным, и я считаю, что могут быть лучшие решения.

Ответы [ 2 ]

2 голосов
/ 28 мая 2020

Использование melt() / dcast():

data[, row := .I
     ][, melt(.SD, id.vars = "row")
        ][order(row, value), paste0(unique(value[!is.na(value)]), collapse = "&&&"), by = row]

    row    V1
 1:   1     1
 2:   2      
 3:   3     1
 4:   4     1
 5:   5 1&&&2
 6:   6 1&&&2
 7:   7     2
 8:   8 1&&&2
 9:   9 1&&&2
10:  10     2

Альтернативное использование вашей исходной функции:

data[, function_non_missing(unlist(.SD)), by = 1:nrow(data)]

    nrow     V1
 1:    1      1
 2:    2       
 3:    3      2
 4:    4 1&&&&2
 5:    5 1&&&&2
 6:    6 1&&&&2
 7:    7      1
 8:    8      2
 9:    9 1&&&&2
10:   10 1&&&&2
0 голосов
/ 28 мая 2020

Вероятно, используется apply?

library(data.table)
data[, col := apply(.SD, 1, function(x) 
           paste(sort(unique(na.omit(x))), collapse = "&&&"))]
data

#     a  b  c   col
# 1:  1 NA  1     1
# 2: NA NA NA      
# 3: NA  1  1     1
# 4:  1  1  1     1
# 5:  2  1  1 1&&&2
# 6:  1  2  1 1&&&2
# 7: NA  2  2     2
# 8: NA  2  1 1&&&2
# 9:  2  2  1 1&&&2
#10:  2 NA  2     2
...