Повторите столбцы на таблице в соответствии с именем - PullRequest
0 голосов
/ 26 апреля 2018

Мне дали один из тех эпических примеров Excel.В широкой таблице указана емкость для пар продуктов (в строках) и машин (в столбцах).Таблица выглядит аналогично приведенной в следующем воспроизводимом примере (обратите внимание на использование решений data.table. data.frame / tidyverse, хотя предпочтительны решения data.table):

a <- data.table(names = c("product 1", "product 2"), "9-10" = c(1, 5), "21-23" = c(3, 2))

> a
       names 9-10 21-23
1: product 1    1     3
2: product 2    5     2

Проблема «9-10» означает, что машины 9 и 10 имеют одинаковую производительность (1 и 5 для продуктов 1 и 2 соответственно).Я ищу способ закончить с таблицей, которая выглядит как b:

> b
       names 9 10 21 23
1: product 1 1  1  3  3
2: product 2 5  5  2  2

Я добился этого с помощью следующего кода:

for (i in unlist(strsplit(names(a)[2:3], split = "-", fixed = TRUE))){
    a[, print(i) := .SD, .SDcols = grep(paste0(i, "\\b"), names(a)[2:3], value = TRUE)]
}

a[, names(a)[2:3] := NULL]

Интересно, что будетболее чистый способ сделать это.

Ответы [ 3 ]

0 голосов
/ 26 апреля 2018

Используя data.table, мы можем просто создать индекс и подмножество, а затем настроить имена.

# data
a <- data.table(names = c("product 1", "product 2"),
                "9-10" = c(1, 5),
                "21-23" = c(3, 2))


# names split
name_pos <- strsplit(names(a), split = "-")
# create index for subsetting based on name_pos
index <- rep(seq_along(name_pos), times = lengths(name_pos))

# index and adjust names
a_final <- a[, ..index]
# thanks to Frank for suggestion
setnames(a_final, unlist(name_pos))
0 голосов
/ 26 апреля 2018

Другая возможность с data.table:

melt(a, id = 1)[, unlist(tstrsplit(variable,'-')), by = .(names, value)
                ][, dcast(.SD, names ~ V1)]

, которая дает:

       names 10 21 23 9
1: product 1  1  3  3 1
2: product 2  5  2  2 5
0 голосов
/ 26 апреля 2018

Решением является использование tidyr как:

library(tidyr)
library(dplyr)
a %>% gather(variable, value, -names) %>% 
  separate(variable, c("col1","col2")) %>% mutate(value2 = value) %>%
  spread(col1, value)  %>% spread(col2, value2) %>%
  group_by(names) %>%
  summarise_all(sum,na.rm = TRUE) %>%
  as.data.frame()
#       names 21 9 10 23
# 1 product 1  3 1  1  3
# 2 product 2  2 5  5  2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...