2016-12-13 3 views
-2

Образец данных:R: Добавить динамическое имя столбца грести в R

df <- data.frame(ProdCode = c("C1","C2"), ProdName = c("Product 1", "Product 2"), Category = c("Categ 1", "Categ 2"), "Jan-16" = c(3,2), "Apr-16" = c(3,""), "Jul-16" = c(5,2), "Oct-16" = c(5,2)) 

Значение, соответствующее каждый месяц и мобильный продукт рейтинг для этого продукта. Это необходимо, чтобы быть в столбце Рейтинг в выходном dataframe:

> df 
    ProdCode ProdName Category Jan.16 Apr.16 Jul.16 Oct.16 
1  C1 Product 1 Categ 1  3  3  5  5 
2  C2 Product 2 Categ 2  2    2  2 

Я выше данных, который требуется в формате ниже:

ProdCode Product.Name Category Rating.Date Rating 
C1   Product 1 Categ 1  Jan-16   3 
C1   Product 1 Categ 1  Apr-16   3 
C1   Product 1 Categ 1  Jul-16   5 
C1   Product 1 Categ 1  Oct-16   5 
C2   Product 2 Categ 2  Jan-16   2 
C2   Product 2 Categ 2  Jul-16   2 
C2   Product 2 Categ 2  Oct-16   2 

Месяц колонки являются динамичными и будет возрастать, например, в будущем в соответствии с продуктом он появится как январь-2017 и т. д. Я мог бы сделать это, используя цикл, но это не стоит использовать R.

+0

Посмотрите на пакет 'reshape2' и, в частности,' melt() 'function – mpjdem

+0

check tidyr :: gather – OmaymaS

+0

@mpjdem, yeah melt() может работать, спасибо –

ответ

0

Это разные другие варианты у нас есть:

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

с использованием melt() from data.frame

library(reshape2) 
df1 = melt(df, id.vars = c("ProdCode" , "ProdName" ,"Category"), measure.vars = 4:7) 
df1 = df1[df1$value != "",] 

использованием melt from data.table)

library(data.table) 
setDT(df) 
melt.data.table(df, 1:3,4:7)[value!=""] # '1:3, 4:7' are the column indexes. read more from ?melt 

# ProdCode ProdName Category variable value 
#1  C1 Product 1 Categ 1 Jan.16  3 
#2  C2 Product 2 Categ 2 Jan.16  2 
#3  C1 Product 1 Categ 1 Apr.16  3 
#5  C1 Product 1 Categ 1 Jul.16  5 
#6  C2 Product 2 Categ 2 Jul.16  2 
#7  C1 Product 1 Categ 1 Oct.16  5 
#8  C2 Product 2 Categ 2 Oct.16  2 

# if you want your specific column names : 

melt.data.table(df, 1:3,4:7, variable.name = "Rating.Date", value.name = "Rating")[Rating!=""] 
# ProdCode ProdName Category Rating.Date Rating 
#1:  C1 Product 1 Categ 1  Jan.16  3 
#2:  C2 Product 2 Categ 2  Jan.16  2 
#3:  C1 Product 1 Categ 1  Apr.16  3 
#4:  C1 Product 1 Categ 1  Jul.16  5 
#5:  C2 Product 2 Categ 2  Jul.16  2 
#6:  C1 Product 1 Categ 1  Oct.16  5 
#7:  C2 Product 2 Categ 2  Oct.16  2 
+0

Просто используйте 'melt()' - если вы дадите ему 'data.table', он будет называть' melt.data.table' под капотом –

+0

@DavidArenburg более чистый код, и быстрее в моем наблюдении –

+1

благодарит за комментарий. @DavidArenburg мне нужно правильно исправить факты. –

0

Мы можем использовать gather, чтобы изменить его на «длинный», filter из заготовок в 'Рейтинг' и arrange 'ProdCode'

library(tidyr) 
library(dplyr) 
gather(df, Rating.Date, Rating, Jan.16:Oct.16) %>% 
      filter(Rating !="") %>% 
      arrange(ProdCode) 
# ProdCode ProdName Category Rating.Date Rating 
#1  C1 Product 1 Categ 1  Jan.16  3 
#2  C1 Product 1 Categ 1  Apr.16  3 
#3  C1 Product 1 Categ 1  Jul.16  5 
#4  C1 Product 1 Categ 1  Oct.16  5 
#5  C2 Product 2 Categ 2  Jan.16  2 
#6  C2 Product 2 Categ 2  Jul.16  2 
#7  C2 Product 2 Categ 2  Oct.16  2 
+0

Нет рейтинга и рейтинга.date в df @akrun –

+0

@user_az Это имя ключа и значения, которое мы предоставляем для создания в выводе – akrun