df1 <- data.frame(a = c(1:5), b = c(6:10), c=c("df1","df1","df1","df1","df1"))
df2 <- data.frame(a = c(1,3,5,7,9), b = c(16:20), c=c("df2","df2","df2","df2","df2"), d= LETTERS[1:5], e= LETTERS[6:10])

Я хотел бы создать новую таблицу, которая выполняет следующие действия:

  1. складывать одну таблицу поверх другой, только если значение в столбце a совпадает (т.е. только 1,3,5)
  2. показывать только столбцы a, b и c (игнорировать столбцы d и e)
  3. всего должно быть 6 строк и 3 столбца, со строками 1-3 из df1 (a = 1,3,5) и строками 4-6 из df2 (a = 1,3,5)
r
0
Vincent Xu 21 Янв 2021 в 04:01

3 ответа

Лучший ответ

База R

common <- intersect(df1$a, df2$a)
rbind(
  subset(df1, a %in% common, select = a:c),
  subset(df1, a %in% common, select = a:c)
)
#    a  b   c
# 1  1  6 df1
# 3  3  8 df1
# 5  5 10 df1
# 11 1  6 df1
# 31 3  8 df1
# 51 5 10 df1

Dplyr

library(dplyr)
bind_rows(
  semi_join(df1, df2, by = "a"),
  semi_join(df2, df1, by = "a")
) %>%
  select(a, b, c)
#   a  b   c
# 1 1  6 df1
# 2 3  8 df1
# 3 5 10 df1
# 4 1 16 df2
# 5 3 17 df2
# 6 5 18 df2
0
r2evans 21 Янв 2021 в 01:38

Вот базовый вариант R с использованием merge и split.default:

df3 <- merge(df1, df2, by = 'a')

result <- subset(do.call(cbind.data.frame, 
                 sapply(split.default(df3, sub('\\..*', '', names(df3))), 
                        unlist, use.names = FALSE)), select = a:c)
result

#  a  b   c
#1 1  6 df1
#2 3  8 df1
#3 5 10 df1
#4 1 16 df2
#5 3 17 df2
#6 5 18 df2
0
Ronak Shah 21 Янв 2021 в 01:41

Используйте semi_join() из пакета dplyr.

df1 <- data.frame(a = c(1:5), b = c(6:10), c=c("df1","df1","df1","df1","df1"))
df2 <- data.frame(a = c(1,3,5,7,9), b = c(16:20), c=c("df2","df2","df2","df2","df2"), d= LETTERS[1:5], e= LETTERS[6:10])

library(dplyr)
new_df <- rbind(semi_join(df1,df2,by="a")[,c(1:3)],semi_join(df2,df1,by="a")[,c(1:3)])
new_df

Полусоединение: возвращает все строки из df1, где есть совпадающие значения в df2, сохраняя только столбцы из df1. Это фильтрующее соединение.

Выход:

> new_df
  a  b   c
1 1  6 df1
2 3  8 df1
3 5 10 df1
4 1 16 df2
5 3 17 df2
6 5 18 df2
0
Divyansh Chaudhary 21 Янв 2021 в 01:20