2015-06-15 3 views
3

Предположим, что я работаю в компании, которая предоставляет ряд различных услуг своим клиентам. Мне был дан отчет о данных о предоставляемых услугах, которые мне нужно проанализировать. Отчет отформатирован таким образом, чтобы его можно было легко читать и печатать, но не подходящим для анализа данных.Преобразование нерегулярных данных в формат, пригодный для использования в R

Формат отчета выглядит следующим образом:

Вход:

customer <- c(1,2,2,3,3,3) 
service1 <- c(1,3,5,1,3,5) 
fee1 <- c(100,290,500,100,300,500) 
service2 <- c("",4,"",2,4,8) 
fee2 <- c("",400,"",200,390,800) 

require(data.table) 
DT <- data.table(customer, service1, fee1, service2, fee2) 

который печатает:

> DT 
    customer service1 fee1 service2 fee2 
1:  1  1 100    
2:  2  3 290  4 400 
3:  2  5 500    
4:  3  1 100  2 200 
5:  3  3 300  4 390 
6:  3  5 500  8 800 

Есть целый ряд клиентов, и для каждого существует ряд услуг, которые они потребляют, и соответствующих сборов. Услуги и сборы печатаются горизонтально в четырех столбцах, а затем переполняются в новую строку. Для каждого клиента может быть любое количество услуг, но каждая услуга может выполняться только один раз для каждого клиента, и плата за услугу может отличаться для каждого клиента. Они, вероятно, всегда печатаются в том же порядке, хотя решение не должно полагаться на это.

Задача состоит в том, чтобы преобразовать данные в полезный формат. Я вижу два разных способа сделать это.

Первый вариант (длинный формат): отрежьте последние два столбца, создайте новую строку для каждого заказчика и заполните содержимое.

Вариант один будет выглядеть следующим образом:

customer service fee 
1:  1  1 100 
2:  2  3 290 
3:  2  4 400 
4:  2  5 500 
5:  3  1 100 
6:  3  2 200 
7:  3  3 300 
8:  3  4 390 
9:  3  5 500 
10:  3  8 800 

Второй вариант (широкий формат): отрезают все строки, кроме первой для каждого клиента, создавать новые столбцы для нарезанных отключения служб, а затем преобразовать службу наклейки в заголовки столбцов (и убедитесь, что все в нужном месте).

Вариант два будет выглядеть следующим образом:

customer service.1 service.2 service.3 service.4 service.5 service.6 service.7 service.8 
1:  1  100                  
2:  2       290  400  500        
3:  3     200  300  390  500       800 

Я могу работать с любым форматом (и преобразования между длиной и шириной довольно легко).

В качестве отправной точки я решил, что мне нужно будет найти либо количество услуг для каждого клиента (вариант 1), либо количество уникальных услуг (вариант 2), развернуть таблицу данных до необходимого размера и перемещать вокруг данных.

Я чувствую, что data.table должен иметь возможность справиться с этим и предпочтет решение с использованием этого пакета из-за его эффективности.

+0

Знаете ли вы, что ваши 'service2' и' fee2' являются символьными векторами? это связано с тем, что при их определении вы смешали числовые символы и 0 char character '' "'. – jangorecki

ответ

4

Я не вижу, как это решаемая с помощью melt, но вы можете использовать простой rbind здесь, например

res <- rbind(DT[, c(1,2:3), with = FALSE], 
      DT[, c(1,4:5), with = FALSE], 
       use.names = FALSE)[service1 != ""] 
res 
#  customer service1 fee1 
# 1:  1  1 100 
# 2:  2  3 290 
# 3:  2  5 500 
# 4:  3  1 100 
# 5:  3  3 300 
# 6:  3  5 500 
# 7:  2  4 400 
# 8:  3  2 200 
# 9:  3  4 390 
# 10:  3  8 800 

В соответствии с вашим вторым выходом, вы можете попробовать что-то вроде

Range <- range(as.numeric(unlist(DT[, c(1, 4), with = FALSE])), na.rm = TRUE) 
res[, service1 := factor(service1, levels = Range[1L]:Range[2L])] 
dcast(res, customer ~ service1, drop = FALSE, fill = "", value.var = "fee1") 
# customer 1 2 3 4 5 6 7 8 
# 1:  1 100       
# 2:  2   290 400 500   
# 3:  3 100 200 300 390 500  800 
+0

Спасибо! Мне кажется, что сейчас я вижу это и все еще не могу добраться ... Я читал 10-минутный справочник и часто задаваемые вопросы, но все же ... Второй вариант, поскольку я не могу установить что-либо новое на свою машину, должен также работать если я разделяю DT по строкам для каждой службы, а затем объединим их вместе. – iraserd

+0

См. Мое редактирование. Вам не нужна версия devel. –

+1

'DT [,. (Клиент, сервис = c (service1, service2), fee = c (fee1, fee2))] [service! =" "]' Является альтернативой для длинной формы – Frank

Смежные вопросы