How to replace values in a dataframe() based on corresponding values in a list()?

Viewed 42

I have a list and a dataframe. The data frame has has two columns, one for song, one for song type. I have a list of songs, for type one song.

allsongs <- data.frame("Song" = c(1, 2, "3A", "9C", 6, 5, "12B", "32A", 18, 27, 24, "1D"),
                        "Type" = 0)

type1songs <- list(c(1, 2, "32A", 6, "1D"))

I would like to use this list to apply the value of "1" to the $Type of all the songs in the dataframe, that are in that list.

So it would look something like this.

   Song Type
1     1    1
2     2    1
3    3A   NA
4    9C   NA
5     6    1
6     5   NA
7   12B   NA
8   32A    1
9    18   NA
10   27   NA
11   24   NA
12   1D    1

How do I do that?

2 Answers

We can use match or %in% - match returns the positions of match and by default the nomatch is NA. Once we get the matching index, create a logical vector with > 0 and coerce it to binary (+)

allsongs$Type <- +(match(allsongs$Song, type1songs[[1]]) > 0)

-output

allsongs
#    Song Type
#1     1    1
#2     2    1
#3    3A   NA
#4    9C   NA
#5     6    1
#6     5   NA
#7   12B   NA
#8   32A    1
#9    18   NA
#10   27   NA
#11   24   NA
#12   1D    1

Or an option with data.table

library(data.table)
setDT(allsongs)[Song %in% type1songs[[1]], Type := 1]

Or with base R

allsongs$Type[allsongs$Song %in% type1songs[[1]]] <- 1

Besides the match approach by @akrun, another base R option might be using factor, e.g.,

within(allsongs, Type <- +(as.integer(factor(Song,levels = type1songs[[1]]))>0))

which gives

   Song Type
1     1    1
2     2    1
3    3A   NA
4    9C   NA
5     6    1
6     5   NA
7   12B   NA
8   32A    1
9    18   NA
10   27   NA
11   24   NA
12   1D    1
Related