2

考虑以下数据框:

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。这两行应该被删除。

我希望我的要求很清楚:-)

亲切的问候!

4

5 回答 5

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”中粘贴的列进行比较。

于 2013-10-09T16:23:55.017 回答
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"))
于 2013-10-09T15:48:32.093 回答
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
于 2013-10-09T16:42:32.307 回答
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 被复制的警告。有人知道该怎么做吗?

于 2013-10-09T16:17:13.853 回答
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
于 2013-10-09T16:50:31.550 回答