如果存在关联,如何用1和0填充矩阵

时间:2014-11-09 14:16:10

标签: r matrix fill

我一直试图从R中的数据框创建一个矩阵,没有成功。我有下一个数据框

Order        Object      idrA   idoA
8001505892  CHR56029398AB   1   1
8001506013  CHR56029398AB   1   2
8001507782  CHR56029398AB   1   3
8001508088  CHR56029398AB   1   4
8001508788  CHR56029398AB   1   5
8001509281  CHR56029398AB   1   6
8001509322  CHR56029398AB   1   7
8001509373  CHR56029398AB   1   8
8001505342  MMRMD343563     2   9
8001506699  MMRMD343563     2   10
8001507102  MMRMD343563     2   11
8001507193  MMRMD343563     2   12
8001508554  MMRMD343563     2   13
8001508654  MMRMD343563     2   14
8001509151  MMRMD343563     2   15
8001509707  MMRMD343563     2   16
8001509712  MMRMD343563     2   17
8001509977  MMRMD343563     2   18
8001510279  MMRMD343563     2   19
8001505342  MMRMD343565     3   9
8001507112  MMRMD343565     3   20
8001507193  MMRMD343565     3   12
8001508554  MMRMD343565     3   13
8001508654  MMRMD343565     3   14
8001509151  MMRMD343565     3   15
8001509707  MMRMD343565     3   16
8001509712  MMRMD343565     3   17
8001509977  MMRMD343565     3   18
8001510279  MMRMD343565     3   19
8001505920  MMRMN146319     4   21
8001506733  MMRMN146319     4   22
8001506929  MMRMN146319     4   23
8001507112  MMRMN146319     4   20
8001507196  MMRMN146319     4   24
8001510302  MMRMN146319     4   25
8001517272  MMRMN146319     4   26
8001506186  MMRMN146320     5   27
8001506733  MMRMN146320     5   22
8001506929  MMRMN146320     5   23
8001507112  MMRMN146320     5   20
8001508638  MMRMN146320     5   28
8001509526  MMRMN146320     5   29
8001505452  SSR664050011    6   30
8001508551  SSR664050011    6   31
8001509229  SSR664050011    6   32
8001510174  SSR664050011    6   33

其中idr是每个对象的ID,ido是每个采购订单的ID。所以我想用行数= N°和N°列= N°对象制作一个matriz,并用1s和0s的向量填充它,当每个顺序购买一些对象时为1如果不是,则为0。

示例:ido=20的订单必须包含此(0,0,1,1,1,0)之类的向量。

我希望我能解释清楚,谢谢!

2 个答案:

答案 0 :(得分:2)

您可以使用xtabs创建交叉表:

重新创建数据:

dat <- read.table(header=TRUE, text="
                  Order        Object      idrA   idoA
                  8001505892  CHR56029398AB   1   1
                  ....
                  8001506013  CHR56029398AB   1   2
                  8001507782  CHR56029398AB   1   3
                  8001509229  SSR664050011    6   32
                  8001510174  SSR664050011    6   33")

创建交叉表:

xtabs(Order ~ idoA + idrA, dat) != 0

    idrA
idoA     1     2     3     4     5     6
  1   TRUE FALSE FALSE FALSE FALSE FALSE
  2   TRUE FALSE FALSE FALSE FALSE FALSE
  ....
  20 FALSE FALSE  TRUE  TRUE  TRUE FALSE
  ....
  32 FALSE FALSE FALSE FALSE FALSE  TRUE
  33 FALSE FALSE FALSE FALSE FALSE  TRUE

要将逻辑值强制转换为数值,您可以使用apply()as.numeric,但之后还有一些工作要替换行名称:

 apply(xtabs(Order ~ idoA + idrA, dat) != 0, 2, as.numeric)

或者,您可以通过向值添加0来使用小技巧。这会将逻辑值强制转换为数字:

 (xtabs(Order ~ idoA + idrA, dat) != 0) + 0

    idrA
idoA 1 2 3 4 5 6
  1  1 0 0 0 0 0
  2  1 0 0 0 0 0
  3  1 0 0 0 0 0
....

答案 1 :(得分:1)

另一种选择是使用acast

中的reshape2
 library(reshape2)
 res1 <- (acast(dat, idoA~idrA, value.var='Order', fill=0)!=0)+0

 head(res1)
#  1 2 3 4 5 6
#1 1 0 0 0 0 0
#2 1 0 0 0 0 0
#3 1 0 0 0 0 0
#4 1 0 0 0 0 0
#5 1 0 0 0 0 0
#6 1 0 0 0 0 0

或使用dplyr/tidyr

library(dplyr)
library(tidyr)
 dat %>% 
     select(-Object) %>% 
     spread(idrA, Order, fill=0) %>%
     mutate_each(funs((!!.)+0), select=-idoA) %>%
     head()
 #idoA 1 2 3 4 5 6
#1    1 1 0 0 0 0 0
#2    2 1 0 0 0 0 0
#3    3 1 0 0 0 0 0
#4    4 1 0 0 0 0 0
#5    5 1 0 0 0 0 0
#6    6 1 0 0 0 0 0