0

So I have a data frame that contains a bunch of transactions with items, kinda like this:

| 1 | 2 | 4  | 5  | 6  |
| 3 | 5 | 8  | 9  |    |
| 1 | 5 | 7  | 10 | 12 |
| 7 | 8 | 10 | 15 | 17 |

I have a list of all the existing items, and now I'd like to convert this to a logical matrix with 0 and 1 values. So if an item exists in a given row, that entry in the matrix should be 1.

Is there an easy way to do this?

Edit : For the logical matrix, we need to generate a column for each item, and a row for each transaction.

Jean-Noël
  • 368
  • 1
  • 6

3 Answers3

3

You may use as.logical.

# for a matrix
apply({m[is.na(m)] <- 0;m}, 2, as.logical)^1
#      [,1] [,2] [,3] [,4]
# [1,]    1    1    1    0
# [2,]    0    1    1    1
# [3,]    1    1    0    1

# works too on data frames
apply({d[is.na(d)] <- 0;d}, 2, as.logical)^1
#      [,1] [,2] [,3] [,4]
# [1,]    1    1    1    0
# [2,]    0    1    1    1
# [3,]    1    1    0    1

Or, using less bytes with credits to @RHertel:

d[] <- +!is.na(d)

Data:

m <- structure(c(1L, NA, 12L, 9L, 2L, 4L, 8L, 6L, NA, NA, 11L, 7L), .Dim = 3:4)
d <- as.data.frame(m)
jay.sf
  • 60,139
  • 8
  • 53
  • 110
1

You can use the following code to make it:

Given M <- as.matrix(df) as the first step to convert data frame to matrix, then use

M[] <- ifelse(!is.na(M>0),1,0)

or

M[] <- +(!is.na(M>0))

you will get the binary matrix M

ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
0

Assuming your data frame is called df, you can do:

df_matrix <- as.matrix(df)
df_matrix[!is.na(df_matrix)] <- 1
df_matrix[is.na(df_matrix)] <- 0
cardinal40
  • 1,245
  • 1
  • 9
  • 11
  • Thanks! The Problem is that my data frame does not have a column for every existing item. Every row only contains the items that are actually in that transaction. – Jonas Weckschmied Jan 16 '20 at 15:28