2013-08-22 4 views
2

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

my.df <- data.frame(person = c('A', 'A', 'B', 'B', 'B', 'C'), 
        week = c(1, 2, 1, 3, 3, 2), 
        event = c('visit', 'buy', 'visit', 'visit', 'buy', 'visit')) 
> my.df 
    person week event 
1  A 1 visit 
2  A 2 buy 
3  B 1 visit 
4  B 3 visit 
5  B 3 buy 
6  C 2 visit 

Желаемая матрица вывода имеет строки как люди, а столбцы - недели. В записи (человек, неделя) я хочу «купить», если человек купил, а если нет, я хочу «посещать», если посетитель посетил, иначе я хочу иметь «нет» в качестве записи. Более конкретно, желаемый результат является следующей матрицей:

> my.mat 
    1  2  3  
A "visit" "buy" "none" 
B "visit" "none" "buy" 
C "none" "none" "visit" 

У меня есть идея, что я должен преобразовать события в число, сделать бросок с максимальным, а затем преобразовать число обратно в событие, но я я не совсем уверен, как это все вместе.

+0

Существует два значения для (B, 3) .. Как вы хотите это решить? (Вы, кажется, взяли последнее значение .. Это то, что вы хотите сделать?) – Arun

+1

Если дубликатов нет (удалив строку 4), вы можете напрямую: 'acast (my.df [-4,] , person ~ week, value.var = "event", fill = "none") 'путем загрузки пакета' reshape2'. – Arun

+0

@Arun Я хочу дать «покупать» приоритет над «посещением», поэтому, если есть несколько значений, я хочу принять самое важное событие. –

ответ

1

Основываясь на ответах @eddi и @Rodrigo, мне удалось найти следующий код, который немного подробный, но работает. Он также работает, если я хочу более сложный порядок событий.

require(reshape2) # For acast(...) 

# Input data frame 
my.df <- data.frame(person = c('A', 'A', 'B', 'B', 'B', 'C'), 
        week = c(1, 2, 1, 3, 3, 2), 
        event = c('visit', 'buy', 'visit', 'visit', 'buy', 'visit')) 

# Convert event into numbers, with buy > visit 
the.levels <- c('visit', 'buy') 
my.df$event <- as.numeric(factor(my.df$event, levels = the.levels)) 

# Build matrix 
temp <- acast(my.df, person ~ week, function(x) {max(x)}, 
      value.var = 'event', fill = 0) 

# Convert event numbers back into text 
number.to.event <- as.list(setNames(c('none', 'visit', 'buy'), 
           as.character(c(0, 1, 2)))) 
# Save row names and column names 
out <- matrix(number.to.event[as.character(temp)], nrow = 3, 
       dimnames = dimnames(temp)) 

> out 
    1  2  3  
A "visit" "buy" "none" 
B "visit" "none" "buy" 
C "none" "visit" "none" 
2

Как Arun указывает, использовать reshape2 пакет:

library(reshape2) 

# there is a variety of ways to get the precedence you like 
# I chose to just sort the strings 
acast(my.df, person ~ week, function(x) {sort(as.character(x))[1]}, 
     value.var = 'event', fill = 'none') 
# 1  2  3  
#A "visit" "buy" "none" 
#B "visit" "none" "buy" 
#C "none" "visit" "none" 
1

Просто кусок кода:

unique(event) 
as.numeric(factor(event)) 
unique(event)[as.numeric(factor(event)[1])] 

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

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