#r #dataframe #merge #match
#r #фрейм данных #слияние #сопоставление
Вопрос:
У меня есть два фрейма данных:
df1 <- data.frame(assoc = c(2, 3.4, 4.6, -2.3, -1, 0.48, -0.4),
con = c("A","B","C","D","E","F","T"))
df2 <- data.frame(pos = c("-3", "-2", "-1", "0", "1", "2", "3"),
col1 = c("A", "B", "B", "T", "T", "D", "E"),
col2 = c("B", "T", "D", "A", "E", "C","F"))
view(df1)
con assoc
A 2
B 3.4
C 4.6
D -2.3
E -1
F 0.48
T -0.4
Я хотел бы создать функцию для сопоставления фреймов данных, чтобы присвоенные значения из df1 отображались в виде новых столбцов в df2. Желаемый результат будет выглядеть следующим образом:
pos col1 con1 col2 con2
-3 A 2 B 3.4
-2 B 3.4 T -0.4
-1 B 3.4 D -2.3
0 T -0.4 A 2
1 T -0.4 E -1
2 D -2.3 C 4.6
3 E -1 F 0.48
Я пытался использовать:
res <- merge(df1, df2)
view(res)
К сожалению, это сработало только для одного примера. Когда я добавил новый столбец, похоже, это не сработало.
Любая помощь будет высоко оценена!
Комментарии:
1. Как
df1
связать сdf2
? Я не вижу ни одного совпадающего столбца
Ответ №1:
Похоже, вы пытаетесь дважды соединить df1 с df2 с помощью разных переменных:
library(tidyr)
df1 %>%
left_join(df1, by = c(col1 = "con")) %>%
left_join(df1, by = c(col2 = "con"))
#> pos col1 col2 assoc.x assoc.y
#> 1 -3 A B 2.0 3.40
#> 2 -2 B T 3.4 -0.40
#> 3 -1 B D 3.4 -2.30
#> 4 0 T A -0.4 2.00
#> 5 1 T E -0.4 -1.00
#> 6 2 D C -2.3 4.60
#> 7 3 E F -1.0 0.48
Или двойное слияние:
merge(merge(df1, df2, by.x = "con", by.y = "col1"),
df2, by.x = "con", by.y = "col2")
#> con assoc pos.x col2 pos.y col1
#> 1 A 2.0 -3 B 0 T
#> 2 B 3.4 -2 T -3 A
#> 3 B 3.4 -1 D -3 A
#> 4 D -2.3 2 C -1 B
#> 5 E -1.0 3 F 1 T
#> 6 T -0.4 0 A -2 B
#> 7 T -0.4 1 E -2 B
Ответ №2:
Вы можете использовать match
для этого две колонки, т.е.
sapply(df2[-1], function(i)df1$assoc[match(i, df1$con)])
col1 col2
[1,] 2.0 3.40
[2,] 3.4 -0.40
[3,] 3.4 -2.30
[4,] -0.4 2.00
[5,] -0.4 -1.00
[6,] -2.3 4.60
[7,] -1.0 0.48
Ответ №3:
Вы имеете в виду merge
вот так?
Reduce(
function(x, y) merge(x, y, by = names(df1)),
lapply(
grep("col", names(df2), value = TRUE),
function(y) merge(df1, df2, by.x = "con", by.y = y)
)
)
что позволяет вам объединяться, если у вас есть нечто большее, чем просто col1
и col2
внутри df2
, что дает вам
assoc con pos.x col2 pos.y col1
1 -0.4 T 0 A -2 B
2 -0.4 T 1 E -2 B
3 -1.0 E 3 F 1 T
4 -2.3 D 2 C -1 B
5 2.0 A -3 B 0 T
6 3.4 B -2 T -3 A
7 3.4 B -1 D -3 A
Ответ №4:
Использование for
цикла
out <- df2
for(cn in c("col1", "col2")) out <- merge(out, df1, by.x = cn, by.y = 'con', all.x = TRUE)