根据r中的列值对数据帧进行子集化

时间:2013-09-19 20:54:27

标签: r dataframe

给出数据框ex:

a <- c(1:3,4:6)
b <- c(2:4,3,2,1)
c <- cbind(a,b)

我想通过删除具有类似比较的行来子集数据帧(例如:row3:3,4与row4:4,3相同),并且只有其中一个。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

假设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="~"),它对矢量进行排序,然后将其转换为长度为一的向量,每个元素用~分隔。

因此整个apply调用将返回一个字符向量,其中每个元素曾经是矩阵的一行。

然后unique只保留唯一元素。排序可确保满足我们的要求。

第二行

strsplit(e,"~")将我们的角色向量拆分为一个单独的形式。在这种情况下,它是一个列表,其中每个元素是构成每一行的数字的字符向量。

sapply(...,as.numeric)as.numeric()应用于列表的每个元素。所以我们将字符向量转换回数字向量。由于s中的sapply代表“简化”,因此会创建一个矩阵。

但这是错误的方向(2x5而不是5x2)! t()将矩阵转换为原始格式。

答案 2 :(得分:1)

在您的示例中,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