【问题标题】:Convert molten data frame to matrix in R将熔融数据框转换为R中的矩阵
【发布时间】:2013-08-22 20:33:13
【问题描述】:

我想编写一个将数据框转换为矩阵的函数。数据框是事件列表。每行对应一个访问或购买产品的人。

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

所需的输出矩阵将行作为人,将列作为周。在 (person, week) 条目中,如果有人购买,我希望有“购买”,如果没有,如果有人访问,我希望有“访问”,否则我希望有“无”作为条目。更具体地说,所需的输出是以下矩阵:

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

我的想法是我应该将事件转换为数字,使用最大值进行强制转换,然后将数字转换回事件,但我不完全确定如何将这些放在一起。

【问题讨论】:

  • (B,3) 有两个值。你想如何解决这个问题? (你好像取了最后一个值。。这是你想做的吗?)
  • 如果没有重复(通过删除第4行),您可以直接通过加载reshape2包来执行:acast(my.df[-4, ], person ~ week, value.var="event", fill="none")
  • @Arun 我想给“购买”优先于“访问”,所以如果有多个值我想采取最重要的事件。

标签: r matrix dataframe reshape2


【解决方案1】:

正如 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"

【讨论】:

    【解决方案2】:

    只是一段代码:

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

    第一行显示你有多少不同的事件。第二个将您的事件转换为数字。第三个将给出与编号元素相关的文本(此处为 1)。

    【讨论】:

      【解决方案3】:

      基于@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"
      

      【讨论】:

        猜你喜欢
        • 2018-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-20
        • 1970-01-01
        • 2019-09-20
        • 2014-12-13
        • 2020-11-25
        相关资源
        最近更新 更多