考虑以下数据框:
df <- data.frame(var1 = 1:5, var2 = c(5,6,7,8,1))
> df
var1 var2
1 1 5
2 2 6
3 3 7
4 4 8
5 5 1
我想删除其值在两列中翻转的所有行。在这种情况下,它将是第1行和第5行,因为第1行中的值1和5被翻转为第5行中的5和1.这两行应该是除去。
我希望我明白要求的是: - )
亲切的问候!
答案 0 :(得分:4)
也许这样的事情也可以起作用:
df <- data.frame(var1 = 1:5, var2 = c(5,6,7,8,1))
df[!do.call(paste, df) %in% do.call(paste, rev(df)), ]
var1 var2
2 2 6
3 3 7
4 4 8
我必须在一些测试用例上测试它,但一般的想法是使用rev
来反转“df”和paste
中列的顺序,将其与“df”中的粘贴列进行比较。
答案 1 :(得分:1)
这是一种简单但不是特别优雅的方式:使用标记制作一个反向数据框,然后将其合并到df
:
# Make a reversed dataset
fd <- data.frame(var1 = df$var2, var2 = df$var1, flag = TRUE)
# Merge it onto your original df, then drop the matched rows and the flag var
df.sub <- subset(merge(x = df, y = fd, by = c("var1", "var2"), all.x = TRUE),
subset = is.na(flag),
select = c("var1", "var2"))
答案 2 :(得分:1)
使用一些数学 - 如果差的和和绝对值相同,那么两行是相同的直到排列:
df[with(df, !duplicated(data.frame(var1 + var2, abs(var1 - var2)), fromLast = TRUE)),]
# var1 var2
#1 1 5
#2 2 6
#3 3 7
#4 4 8
编辑应该更仔细地阅读问题,删除两个重复项,请按照Ananda的建议:
df.ind = with(df, data.frame(var1 + var2, abs(var1 - var2)))
df[!duplicated(df.ind) & !duplicated(df.ind, fromLast = TRUE),]
# var1 var2
#2 2 6
#3 3 7
#4 4 8
答案 3 :(得分:0)
如果创建副本不会导致内存问题,那么这也可以 -
df <- data.frame(var1 = 1:5, var2 = c(5,6,7,8,1))
df2 <- data.frame(var12 = 1:5, var22 = c(5,6,7,8,1))
df3 <- merge(df,df2, by.x = 'var2', by.y = 'var12', all.x = TRUE)
df3 <- subset(
df3,
is.na(var22),
select = c('var1','var2')
)
输出:
> df3
var1 var2
3 2 6
4 3 7
5 4 8
我尝试将df与df合并但是会发出关于列var2被复制的警告。谁知道该怎么办?
答案 4 :(得分:0)
如果您可以假设数据框中没有重复项。这是一个单行答案,但仍然不太简洁:
df[!duplicated(rbindlist(list(df,df[,2:1])))[nrow(df) + 1:nrow(df)],]
## var1 var2
## 2 2 6
## 3 3 7
## 4 4 8
此处需要 rbindlist
,因为rbind(df,df[,2:1])
将按列名而不是索引匹配,因此另一个选项类似于rbind(df,setnames(df[,2:1],names(df)))
。如果你想保留原件的重复,这会让人更加不愉快:
> df <- data.frame(var1 = 1:5, var2 = c(5,6,7,8,1))
> df<-rbind(df,c(2,6))
> df[!duplicated(rbindlist(list(df,df[,2:1])))[nrow(df)+1:nrow(df)],]
var1 var2
2 2 6
3 3 7
4 4 8
> df[!duplicated(rbindlist(list(df,df[,2:1])))[nrow(df)+1:nrow(df)] | duplicated(df),]
var1 var2
2 2 6
3 3 7
4 4 8
6 2 6