Here is a simple solution that uses base R.
# Dummy data
df6 <- data.frame(
id = c(1, 2, 3),
v1 = c(0, 2, 0),
v2 = c(0, 0, 1),
v3 = c(3, 0, 0)
)
df_yummy <- data.frame(
VarId = c("v1", "v2", "v3"),
VarName = c("Apple", "Lemon", "Peach"),
Yummyness = c(2, 1, 3)
)
df6$VarId <- names(df6[-1])[apply(X = df6[-1] > 0, MARGIN = 1, FUN = which)]
df_result <- merge(df6, df_yummy)[, c("id", "VarName", "Yummyness")]
names(df_result) <- c("id", "Fruit", "Yummyness")
> df_result[order(df_result$id), ]
id Fruit Yummyness
3 1 Peach 3
1 2 Apple 2
2 3 Lemon 1
The crux of this solution is found in apply(X = df6[-1] > 0, MARGIN = 1, FUN = which). What this does is take your df6 and removes the first column (the [-1]) portion and then finds which records are greater than zero. We then use the apply function to apply the which function over the rows (the MARGIN = 1) portion. This means that for every row, we are returning the index which is non-zero. We pass this to names() to get the right name for each, and then the rest is just some joins.
Here's a slightly more compact version that uses the data.table package.
library(data.table)
# Dummy data
df6 <- data.table(
id = c(1, 2, 3),
v1 = c(0, 2, 0),
v2 = c(0, 0, 1),
v3 = c(3, 0, 0)
)
df_yummy <- data.table(
VarId = c("v1", "v2", "v3"),
VarName = c("Apple", "Lemon", "Peach"),
Yummyness = c(2, 1, 3)
)
df6[, VarId := names(df6)[-1][which(.SD > 0)], by = id]
df_result <- merge(df6, df_yummy)[order(id), list(id, Fruit = VarName, Yummyness)]
This operates on much the same principle; we use the which function on the data.table specific .SD, by id, and then use this to pick the right name. This ends up slightly more compact because of the DT syntax but isn't fundamentally all that different.