这是tidyverse 的一个选项。循环across 'df2' 的'var' 列中指定的列名,replace TRUEvalues 由matching 与'var' 对应的'weight' 元素柱子。然后,我们使用rowSums根据每行非零元素的数量创建一个“状态”列
library(dplyr)
df1 %>%
mutate(across(df2$var,
~ replace(., ., df2$weight[match(cur_column(), df2$var)]))) %>%
mutate(Status = case_when(rowSums(.[df2$var] > 0) > 1
~ 'Multiple', TRUE ~ 'Single'))
-输出
id v1 v2 v3 v4 Status
1 1 1 4 0 0 Multiple
2 2 0 0 2 0 Single
3 3 1 0 0 0 Single
4 4 0 4 2 5 Multiple
或使用base R
df1new <- cbind(df1[1], setNames(df2$weight,
df2$var)[col(df1[df2$var])] * df1[df2$var])
df1new$Status <- c("Single", "Multiple")[1 + (rowSums(df1new[df2$var] > 0) > 1)]
-输出
> df1new
id v1 v2 v3 v4 Status
1 1 1 4 0 0 Multiple
2 2 0 0 2 0 Single
3 3 1 0 0 0 Single
4 4 0 4 2 5 Multiple
或者另一个选项是来自base R的Map
lst1 <- Map(`*`, df1[df2$var], df2$weight)
cbind(df1[1], lst1, Status = c('Single', 'Multiple')[1 + (rowSums(df1[-1]) > 1)])
id v1 v2 v3 v4 Status
1 1 1 4 0 0 Multiple
2 2 0 0 2 0 Single
3 3 1 0 0 0 Single
4 4 0 4 2 5 Multiple
数据
df1 <- structure(list(id = 1:4, v1 = c(TRUE, FALSE, TRUE, FALSE), v2 = c(TRUE,
FALSE, FALSE, TRUE), v3 = c(FALSE, TRUE, FALSE, TRUE), v4 = c(FALSE,
FALSE, FALSE, TRUE)), class = "data.frame", row.names = c(NA,
-4L))
df2 <- structure(list(var = c("v1", "v2", "v3", "v4"), weight = c(1L,
4L, 2L, 5L)), class = "data.frame", row.names = c(NA, -4L))