Создайте новый фрейм данных в соответствии с контрастом между двумя похожими
У меня есть датафрейм, сделанный так:
X Y Z T
1 2 4 2
3 2 1 4
7 5 NA 3
После нескольких шагов (не важно, какой именно) я получил этот df:
X Y Z T
1 2 4 2
3 2 NA 4
7 5 NA 3
я хочу получить новый фрейм данных, созданный только теми строками, которые не изменились во время шагов; результат будет таким:
X Y Z T
1 2 4 2
7 5 NA 3
Как я мог сделать?
4 ответа
Один вариант с base R
будет paste
строки каждого набора данных вместе и сравнить (==
) создать логический вектор, который мы используем для подмножества нового набора данных
dfO[do.call(paste, dfO) == do.call(paste, df),]
# X Y Z T
#1 1 2 4 2
#3 7 5 NA 3
где "dfO" - старый набор данных, а "df" - новый
Вы можете использовать dplyr intersect
функция:
library(dplyr)
intersect(d1, d2)
# X Y Z T
#1 1 2 4 2
#2 7 5 NA 3
Это data.frame-эквивалент базы R intersect
функция.
Если вы работаете с data.table
s, этот пакет также предоставляет такую функцию:
library(data.table)
setDT(d1)
setDT(d2)
fintersect(d1, d2)
# X Y Z T
#1: 1 2 4 2
#2: 7 5 NA 3
Я боюсь, что ни semi join
ни intersect
или же merge
правильные ответы. merge
а также intersect
не будет правильно обрабатывать дубликаты строк. Полу соединение изменит порядок строк.
С этой точки зрения, я думаю, что единственно верным является подход Акруна.
Вы также можете сделать что-то вроде:
df1[rowSums(((df1 == df2) | (is.na(df1) & is.na(df2))), na.rm = T) == ncol(df1),]
Но я думаю, что путь Акруна более элегантен и, скорее всего, будет лучше с точки зрения скорости.
Другая dplyr
решение: semi_join
,
dt1 %>% semi_join(dt2, by = colnames(.))
X Y Z T
1 1 2 4 2
2 7 5 NA 3
Данные
dt1 <- read.table(text = "X Y Z T
1 2 4 2
3 2 1 4
7 5 NA 3",
header = TRUE, stringsAsFactors = FALSE)
dt2 <- read.table(text = " X Y Z T
1 2 4 2
3 2 NA 4
7 5 NA 3",
header = TRUE, stringsAsFactors = FALSE)