给定一个数据框 ex:
a <- c(1:3,4:6)
b <- c(2:4,3,2,1)
c <- cbind(a,b)
我想通过删除具有相似比较的行来对数据框进行子集化(例如:row3:3,4 与 row4:4,3 相同)并且只有其中一个。
a <- c(1:3,4:6)
b <- c(2:4,3,2,1)
d <- cbind(a,b)
e <- t(apply(d,1,function(x){x[order(x)]}))
d <- d[!duplicated(e),]
> d
a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
[4,] 5 2
[5,] 6 1
假设d
是您的矩阵,而不是c
:
e <- unique(apply(d,1,function(x) paste(sort(x),collapse="~")))
> t(sapply(strsplit(e,"~"),as.numeric))
[,1] [,2]
[1,] 1 2
[2,] 2 3
[3,] 3 4
[4,] 2 5
[5,] 1 6
分解它:
第一行
apply(d,1,function(x) ... )
获取 d 的每一行并将其作为向量传递x
给我在...
这里调用的匿名函数。
函数体是paste(sort(x),collapse="~")
,它对向量进行排序,然后将其转换为长度为一的向量,每个元素由 a 分隔~
。
因此,整个apply
调用将返回一个字符向量,其中每个元素曾经是矩阵的一行。
然后unique
只保留独特的元素。排序确保这符合我们的要求。
第二行
strsplit(e,"~")
将我们的字符向量拆分回一个单独的形式。在这种情况下,它是一个列表,其中每个元素都是组成每一行的数字的字符向量。
sapply(...,as.numeric)
适用as.numeric()
于列表的每个元素。所以我们将字符向量转换回数字向量。由于s
insapply
代表“简化”,它将由此创建一个矩阵。
但这是错误的方向(2x5 而不是 5x2)! t()
将矩阵转置为原始形式。
在您的示例中, c 不是 data.frame 而是矩阵。c 不应用作变量名,如其他所述。
在一行中,您可以执行以下操作:
a <- c(1:3,4:6)
b <- c(2:4,3,2,1)
cc <- cbind(a,b)
cc[!duplicated(t(apply(cc,1,sort))), ]
a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
[4,] 5 2
[5,] 6 1