Из булевой таблицы сохраните списки с существующими значениями - PullRequest
1 голос
/ 24 мая 2019

Наличие логического фрейма, подобного следующему:

dftest <- data.frame(id = c("A1","A2","A3","A4","A5"), stock1= c(1,0,0,1,0), stock2 = c(1,1,0,1,0), stock3 = c(0,1,0,0,0))



id stock1 stock2 stock3
A1      1      1      0
A2      0      1      1
A3      0      0      0
A4      1      1      0
A5      0      0      0

Как можно извлечь списки, подобные этому:

stock1 = c("A1,","A4")
stock2 = c("A1","A2","A4")
stock3 = c("A2")

Ответы [ 5 ]

3 голосов
/ 24 мая 2019

Одно решение с lapply и простой настройкой:

lapply(names(dftest)[-1], function(x) dftest[dftest[x] == 1, 'id'])

#[[1]]
#[1] A1 A4
#5 Levels: A1 A2 A3 ... A5

#[[2]]
#[1] A1 A2 A4
#5 Levels: A1 A2 A3 ... A5

#[[3]]
#[1] A2
#5 Levels: A1 A2 A3 ... A5

Ваш столбец идентификатора в настоящее время имеет фактор типа. Если вы не хотите видеть уровни в выходных данных, просто преобразуйте их в символ, т.е. dftest$id <- as.character(dftest$id)

1 голос
/ 24 мая 2019

Игра с data.table:

library(data.table)
data.table::melt(dftest, id.vars = "id")[as.logical(value), list(list(id)), by = variable][[2]]

[[1]]
[1] A1 A4
Levels: A1 A2 A3 A4 A5

[[2]]
[1] A1 A2 A4
Levels: A1 A2 A3 A4 A5

[[3]]
[1] A2
Levels: A1 A2 A3 A4 A5
1 голос
/ 24 мая 2019
    stocks <- list(NULL)

    for (i in 2: ncol(dftest)) {
      stocks[[i-1]] <- dftest$id[dftest[,i]==1]
    }

    names(stocks) <- colnames(dftest)[2: ncol(dftest)]

Результаты следующие.

>stocks
$stock1
[1] A1 A4
Levels: A1 A2 A3 A4 A5

$stock2
[1] A1 A2 A4
Levels: A1 A2 A3 A4 A5

$stock3
[1] A2
Levels: A1 A2 A3 A4 A5
0 голосов
/ 24 мая 2019

Вот вариант с tidyverse

library(tidyverse)
gather(dftest, key, val, -id) %>% 
    filter(val == 1) %>%
    group_split(key) %>%
     map(pluck, 'id')
#[[1]]
#[1] A1 A4
#Levels: A1 A2 A3 A4 A5

#[[2]]
#[1] A1 A2 A4
#Levels: A1 A2 A3 A4 A5

#[[3]]
#[1] A2
#Levels: A1 A2 A3 A4 A5

Или с использованием map

map(dftest[-1], ~ as.character(dftest$id)[!! .x])
#$stock1
#[1] "A1" "A4"

#$stock2
#[1] "A1" "A2" "A4"

#$stock3
#[1] "A2"

Или с map и discard

map(dftest[-1], ~ discard(dftest$id, !.x))

Или опция с base R с использованием split

with(subset(cbind(dftest['id'], stack(dftest, -id)), 
          values == 1), split(as.character(id), ind))
#$stock1
#[1] "A1" "A4"

#$stock2
#[1] "A1" "A2" "A4"

#$stock3
#[1] "A2"

Или с использованием split путем репликации столбца 'id' и names

split(dftest[col(dftest[-1])][c(!!dftest[-1])], 
         names(dftest)[-1][col(dftest[-1])][c(!!dftest[-1])])
0 голосов
/ 24 мая 2019

Другим вариантом может быть использование mapply, преобразование 1/0 данных в логические и подмножество соответствующих id с из каждого столбца, чтобы получить список id с.

mapply(`[`, dftest["id"], data.frame(dftest[-1] == 1), USE.NAMES = FALSE)

#[[1]]
#[1] "A1" "A4"

#[[2]]
#[1] "A1" "A2" "A4"

#[[3]]
#[1] "A2"

данные

dftest <- data.frame(id = c("A1","A2","A3","A4","A5"),
                     stock1= c(1,0,0,1,0), 
                     stock2 = c(1,1,0,1,0), 
                     stock3 = c(0,1,0,0,0), stringsAsFactors = FALSE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...