考虑以下数据框:
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。这两行应该被删除。
我希望我的要求很清楚:-)
亲切的问候!
考虑以下数据框:
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。这两行应该被删除。
我希望我的要求很清楚:-)
亲切的问候!
也许这样的事情也可以工作:
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”中粘贴的列进行比较。
这是一个简单但不是特别优雅的方法:使用标志创建一个反向数据帧,然后将其合并到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"))
使用一些数学 - 如果差的总和和绝对值相同,则两行在排列之前是相同的:
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
如果创建副本不会导致内存问题,那么这也可以 -
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 被复制的警告。有人知道该怎么做吗?
如果您可以假设数据框中没有重复项。这是一个单行答案,但仍然不太简洁:
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