Объединение двух фреймов данных для вычисления переменной, когда имена столбцов равны значениям строк - PullRequest
0 голосов
/ 17 декабря 2018

У меня есть два фрейма данных: один фрейм данных, который имеет дихотомические переменные, представляющие, присутствует ли совпадение строк, и второй фрейм данных, который применяет «веса» для этой строки для разных измерений.

Например, 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")

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Мы можем взять скалярное произведение двух 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
0 голосов
/ 17 декабря 2018

Это то, что вы хотите?

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...