You could exploit the vectorization of == more. Basically it's df1$Item == df1[2:5] gives a boolean matrix then apply which over MARGIN=1 i.e. over the rows.
So if your data looks like this
df1
# Item TopRight TopLeft BottomRight BottomLeft
# 1 bed.png flag.png bed.png stars.png stripes.png
# 2 stripes.png flag.png bed.png stars.png stripes.png
# 3 foo.png foo.png bar.png baz.png bam.png
# 4 baz.png foo.png bar.png baz.png bam.png
you may do:
transform(df1, target=names(df1)[2:5][apply(Item == df1[2:5], 1, which)])
# Item TopRight TopLeft BottomRight BottomLeft target
# 1 bed.png flag.png bed.png stars.png stripes.png TopLeft
# 2 stripes.png flag.png bed.png stars.png stripes.png BottomLeft
# 3 foo.png foo.png bar.png baz.png bam.png TopRight
# 4 baz.png foo.png bar.png baz.png bam.png BottomRight
If it rather looks like that
df2
# Item TopRight TopLeft BottomRight BottomLeft
# 1 bed.png flag.png bed.png stars.png stripes.png
# 2 stripes.png flag.png bed.png stars.png stripes.png
# 3 foo.png foo.png bar.png baz.png bam.png
# 4 baz.png foo.png bar.png baz.png bam.png
# 5 -1 foo.png bar.png baz.png bam.png
# 6 -1 -1 -1 -1 -1
you could do:
within(df2, {
target <- Vectorize(toString)(apply(Item == df2[2:5], 1, \(x)
names(which(x))))
target <- replace(target, target == "", NA)
})
df2
# Item TopRight TopLeft BottomRight BottomLeft target
# 1 bed.png flag.png bed.png stars.png stripes.png TopLeft
# 2 stripes.png flag.png bed.png stars.png stripes.png BottomLeft
# 3 foo.png foo.png bar.png baz.png bam.png TopRight
# 4 baz.png foo.png bar.png baz.png bam.png BottomRight
# 5 -1 foo.png bar.png baz.png bam.png <NA>
# 6 -1 -1 -1 -1 -1 TopRight, TopLeft, BottomRight, BottomLeft
Data:
df1 <- structure(list(Item = c("bed.png", "stripes.png", "foo.png",
"baz.png"), TopRight = c("flag.png", "flag.png", "foo.png", "foo.png"
), TopLeft = c("bed.png", "bed.png", "bar.png", "bar.png"), BottomRight = c("stars.png",
"stars.png", "baz.png", "baz.png"), BottomLeft = c("stripes.png",
"stripes.png", "bam.png", "bam.png")), class = "data.frame", row.names = c(NA,
-4L))
df2 <- structure(list(Item = c("bed.png", "stripes.png", "foo.png",
"baz.png", "-1", "-1"), TopRight = c("flag.png", "flag.png",
"foo.png", "foo.png", "foo.png", "-1"), TopLeft = c("bed.png",
"bed.png", "bar.png", "bar.png", "bar.png", "-1"), BottomRight = c("stars.png",
"stars.png", "baz.png", "baz.png", "baz.png", "-1"), BottomLeft = c("stripes.png",
"stripes.png", "bam.png", "bam.png", "bam.png", "-1")), class = "data.frame", row.names = c(NA,
-6L))