Как свернуть уникальные повторяющиеся столбцы в уникальные столбцы в R? - PullRequest
0 голосов
/ 14 апреля 2019

Решение

Я пошел с решениями, предоставленными @MauritsEvers и @akrun ниже.

Вопрос

Для фрейма данных я хочу сохранить только 1 столбец каждого набора повторяющихся столбцов. Кроме того, сохраняемый столбец принимает имя, которое является объединением всех имен столбцов в наборе дубликатов столбцов. Во фрейме данных есть несколько наборов повторяющихся столбцов. Фрейм данных содержит десятки тысяч столбцов, поэтому использование цикла for может занять слишком много времени.

Я пробовал использовать комбинацию duplicate (), summary (), aggregate (), lapply (), apply () и использование циклов for.

Фрейм входных данных (df_in):

0 1 2 3 4 5 6 7
0 1 0 0 1 0 1 1
0 1 0 1 1 0 0 0
1 0 1 0 0 1 1 0

Фрейм выходных данных (df_out):

0-2-5 1-4 3 6 7
0     1   0 1 1
0     1   1 0 0
1     0   0 1 0

Ответы [ 2 ]

2 голосов
/ 14 апреля 2019

Вот вариант с tidyverse.Мы gather данных в «длинном» формате, конвертируем «значение» в строку, сгруппированную по «значению», paste ключевой столбец вместе, разделяем строки «значения» и затем spreadстолбец 'value' для получения ожидаемого результата

library(tidyverse)
gather(df_in) %>% 
   group_by(key) %>%
   summarise(value = toString(value)) %>% 
   group_by(value) %>% 
   summarise(key = paste(key, collapse="-")) %>% 
   separate_rows(value) %>% 
   group_by(key) %>%
   mutate(n = row_number()) %>% 
   spread(key, value) %>%
   select(-n)
# A tibble: 3 x 5
#  `0-2-5` `1-4` `3`   `6`   `7`  
#  <chr>   <chr> <chr> <chr> <chr>
#1 0       1     0     1     1    
#2 0       1     1     0     0    
#3 1       0     0     1     0    

Или другой вариант с tidyverse будет

t(df_in) %>%
    as.data.frame %>%
    mutate(grp = group_indices(., V1, V2, V3)) %>%
    mutate(rn = row_number() - 1) %>% 
    group_split(grp, keep = FALSE) %>% 
    map_dfc(~ .x %>% 
           mutate(rn = str_c(rn, collapse="-")) %>% 
           slice(1)  %>% 
           gather(key, val, -rn) %>% 
           rename(!! .$rn[1] := val) %>% 
           select(ncol(.)))
# A tibble: 3 x 5
#  `0-2-5`   `3`   `7`   `6` `1-4`
#    <int> <int> <int> <int> <int>
#1       0     0     1     1     1
#2       0     1     0     0     1
#3       1     0     0     1     0

Или мы также можем сделать это с data.table методы

library(data.table)
dcast(melt(as.data.table(t(df_in))[, grp := .GRP, .(V1, V2, V3)][, 
     c(.SD[1], cn = paste(.I-1, collapse="-")) , .(grp)],
      id.var = c('cn', 'grp')), variable ~ cn, value.var = 'value')[, 
        variable := NULL][]
#    0-2-5 1-4 3 6 7
#1:     0   1 0 1 1
#2:     0   1 1 0 0
#3:     1   0 0 1 0

данные

df_in <- structure(list(`0` = c(0L, 0L, 1L), `1` = c(1L, 1L, 0L), `2` = c(0L, 
 0L, 1L), `3` = c(0L, 1L, 0L), `4` = c(1L, 1L, 0L), `5` = c(0L, 
 0L, 1L), `6` = c(1L, 0L, 1L), `7` = c(1L, 0L, 0L)),
  class = "data.frame", row.names = c(NA, -3L))
1 голос
/ 14 апреля 2019

Вы можете сделать следующее в базе R

  1. Получить индексы идентичных столбцов

    idx <- split(seq_along(names(df)), apply(df, 2, paste, collapse = "_"))
    
  2. Сортировка индексов от низкого к высокому

    idx <- idx[order(sapply(idx, function(x) x[1]))]
    
  3. Имена idx как конкатенация имен столбцов

    names(idx) <- sapply(idx, function(x) paste(names(df)[x], collapse = "_"))
    
  4. Создание финала matrix

    sapply(idx, function(x) df[, x[1]])
    #     col0_col2_col5 col1_col4 col3_col6 col7
    #[1,]              0         1         1    1
    #[2,]              0         1         0    0
    #[3,]              1         0         1    0
    

Обратите внимание, что результирующий объект - matrix, поэтому, если вам нужно data.frame, просто приведите as.data.frame.


Пример данных

Я немного изменил ваши данные выборки, чтобы в именах столбцов не было чисел.

df <- read.table(text =
    "col0 col1 col2 col3 col4 col5 col6 col7
0 1 0 1 1 0 1 1
0 1 0 0 1 0 0 0
1 0 1 1 0 1 1 0", header = T)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...