two - operações derivadas álgebra relacional



Encontre complemento de um quadro de dados(anti-junção) (5)

Experimente o comando %in% e inverta-o com !

df[!df$heads %in% df1$heads,]

Eu tenho dois quadros de dados (df e df1). df1 é um subconjunto de df. Eu quero obter um quadro de dados que é o complemento de df1 em df, ou seja, retornar linhas do primeiro conjunto de dados que não correspondem no segundo. Por exemplo, deixe,

quadro de dados df:

heads
row1
row2
row3
row4
row5

quadro de dados df1:

heads
row3
row5

Então a saída desejada df2 é:

heads
row1
row2
row4

Answer #1

O dplyr também possui setdiff() que lhe dará a

setdiff(bigFrame, smallFrame) os registros extras na primeira tabela.

portanto, para o exemplo do OP, o código seria setdiff(df, df1)

O dplyr possui muitas funcionalidades excelentes: para um guia rápido e fácil, veja here.


Answer #2

Outra opção, usando a base R e a função setdiff :

df2 <- data.frame(heads = setdiff(df$heads, df1$heads))

setdiff funciona exatamente como você imagina; pegue os dois argumentos como conjuntos e remova todos os itens do segundo do primeiro.

Acho setdiff mais legível %in% e prefiro não exigir bibliotecas adicionais quando não precisar delas, mas a resposta que você usa é em grande parte uma questão de gosto pessoal.


Answer #3

Resposta tardia, mas para outra opção, podemos tentar fazer uma anti-junção formal do SQL, usando o pacote sqldf :

library(sqldf)
sql <- "SELECT t1.heads
        FROM df t1 LEFT JOIN df1 t2
            ON t1.heads = t2.heads
        WHERE t2.heads IS NULL"
df2 <- sqldf(sql)

O pacote sqldf pode ser útil para os problemas que são facilmente formulados usando a lógica SQL, mas talvez menos facilmente usando o R base ou outro pacote R.


Answer #4

Você também pode fazer algum tipo de anti-junção com a data.table binária de data.table s

library(data.table)
setkey(setDT(df), heads)[!df1]
#    heads
# 1:  row1
# 2:  row2
# 3:  row4

EDIT: Iniciando o data.table v1.9.6 + , podemos associar o data.tables sem configurar as teclas enquanto estiver usando o

setDT(df)[!df1, on = "heads"]

EDIT2: Iniciando o data.table v1.9.8 + fsetdiff foi introduzido, que é basicamente uma variação da solução acima, apenas sobre todos os nomes de colunas da tabela x data.table, por exemplo, x[!y, on = names(x)] . Se all estiver definido como FALSE (o comportamento padrão), somente as linhas exclusivas em x serão retornadas. Para o caso de apenas uma coluna em cada data.table, o seguinte será equivalente às soluções anteriores

fsetdiff(df, df1, all = TRUE)




r-faq