我有两个数据框:一个数据框具有表示变量是否存在字符串匹配的二分变量,另一个数据框在不同维度上对该字符串应用“权重”。
例如,df1
可能看起来像这样:
organic gluten_free kosher sugar_free
1 0 0 0
1 1 0 1
1 1 0 1
0 0 1 0
1 0 1 0
第二个数据帧(df2
中的行值应该与df1
中的列名的值匹配,并与该值匹配每行代表一个重量。
attribute eco-friendly healthy
organic 2 3
gluten_free 1 4
kosher 3 3
sugar_free 2 3
然后我想计算df1
中的colname
与df1
中的行值相等时df2
中每个行值的权重乘积索引。为了清楚起见,我在下面包括了eco-friendly
索引的具体计算:
organic gluten_free kosher sugar-free eco-friendly
1 0 0 0 (1*2 + 0*1 + 0*3 + 0*2)
1 1 0 1 (1*2 + 1*1 + 0*3 + 1*2)
1 1 0 1 (1*2 + 1*1 + 0*3 + 1*2)
0 0 1 0 (0*2 + 0*1 + 1*3 + 0*2)
1 0 1 0 (1*2 + 0*1 + 1*3 + 0*2)
我编写了一个非常丑陋且缓慢的循环函数来完成此任务,但相信存在更优雅的解决方案。下面是一些其他示例数据。
> dput(df1[1:100,])
structure(list(organic = c("0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"), gluten_free = c("0", "1", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "1", "1", "1", "1", "1", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "1", "0", "1", "1", "1", "1", "1", "1", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "1", "0", "0", "0", "0", "0", "1", "0", "1", "0"), kosher = c("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "1", "1", "1", "0", "1", "1", "0", "1", "1", "1", "1", "1", "1", "1", "0", "0", "1", "1", "0", "0", "1", "0", "0", "0", "1")), row.names = c("2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "15", "17", "18", "19", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "77", "78", "79", "80", "81", "83", "84", "85", "86", "87", "88", "91", "92", "93", "95", "97", "98", "101", "103", "105", "106", "108", "117", "124", "125", "127", "129", "131", "132", "133", "136", "137"), class = "data.frame")
> dput(df2[1:3,])
structure(list(attribute = c("organic", "gluten_free", "kosher"), eco_friendly = c(1L, 3L, 2L), healthy = c(2L, 0L, 1L)), row.names = 1:3, class = "data.frame")
答案 0 :(得分:3)
我们可以取两个df
的点积,请记住%*%
运算符仅适用于数字矩阵:
df1[] <- lapply(df1, as.numeric)
output <- cbind(df1, as.matrix(df1) %*% as.matrix(df2[,-1]))
这样做的缺点是df1
中的列和df2
中的行必须以正确的顺序排列。为确保列顺序和行顺序匹配,我们可以使用以下内容代替df2[,-1]
:
df2[match(names(df1), df2$attribute),-1]
输出:
> head(output)
organic gluten_free kosher eco_friendly healthy
2 0 0 0 0 0
3 0 1 0 3 0
4 0 0 0 0 0
5 0 0 0 0 0
6 0 1 0 3 0
7 0 0 0 0 0
答案 1 :(得分:0)
这是您想要的吗?
df <- data.frame(organic = c(1, 1, 1, 0, 1), gluten_free = c(0, 1, 1, 0, 0),
kosher = c(0, 0, 0, 1, 1), sugar_free = c(0, 1, 1, 0, 0))
df %>% mutate(eco_friendly = organic * 2 + gluten_free * 1 + kosher * 3 + sugar_free * 2)