R dataframe - 如何提取唯一值

时间:2013-02-23 16:16:58

标签: r unique match plyr

我正在尝试从数据集中提取SUBJBLKTR的每个组合的第一条记录。简化的集合sampleData是:

SUBJ BLK TR    BEG    END
1  1234   1  1 111021 111021
2  1234   1  1 111400 111021
3  1234   1  1 111566 111021
4  1234   1  1 111765 111021
5  1234   2  2 132050 133113
6  1234   2  2 133123 133113
7  1234   2  2 133479 133113
8  1234   2  2 133762 133113
9  5678   1  1  82503  82502
10 5678   1  1  82902  82502
11 5678   1  1  83102  82502
12 5678   1  1  83310  82502
13 5678   2  2 274870 288224
14 5678   2  2 288225 288224
15 5678   2  2 288535 288224
16 5678   2  2 288802 288224

当我尝试这个时:

ddplyFirst <- ddply(sampleData, .(SUBJ, BLK, TR), summarize, 
                        Tr.match = match(unique(TR), TR))

我明白了:

ddplyFirst
  SUBJ BLK TR Tr.match
1 1234   1  1        1
2 1234   2  2        1
3 5678   1  1        1
4 5678   2  2        1

我不知道如何从这个到我想要的内容,包括BEGEND值或BEG - END

现在,事实证明,在上面的示例中,END是一个唯一的数字,所以我可以这样做:

first <- with(sampleData, match(unique(END), END))

给了我:

sampleData[first,]
   SUBJ BLK TR    BEG    END
1  1234   1  1 111021 111021
5  1234   2  2 132050 133113
9  5678   1  1  82503  82502
13 5678   2  2 274870 288224

问题是完整的数据集 202,616条记录很长,我无法保证BEGEND具有SUBJ的不同组合的唯一值, BLKTR

此外,我想学习如何解决更一般的案例,对我来说,现在将获得每个SUBJBLKTR组合中的第一条记录。

当然,更常见的情况是在每个SUBJBLKTR组合中获取第n条记录。如果有人能告诉我如何做这些“更多”一般或“最”通用解决方案中的一个或另一个,我将非常感激。

5 个答案:

答案 0 :(得分:3)

此处无需使用summarise,您可以执行此操作(使用head获取第一行)

 ddply(sampleData, .(SUBJ, BLK, TR), function(x) head(x,1))
  SUBJ BLK TR    BEG    END
1 1234   1  1 111021 111021
2 1234   2  2 132050 133113
3 5678   1  1  82503  82502
4 5678   2  2 274870 288224

或者更一般地获得第n行。你可以这样做:

ddply(sampleData, .(SUBJ, BLK, TR), function(x) x[min(row.n,nrow(x),])

答案 1 :(得分:2)

您可以通过仅对其进行索引来访问第1或第n条记录(假设每个组都存在nth索引):

idx <- 2
ddply(sampleData, .(SUBJ, BLK, TR), summarise, BEG=BEG[idx], END=END[idx])

#   SUBJ BLK TR    BEG    END
# 1 1234   1  1 111400 111021
# 2 1234   2  2 133123 133113
# 3 5678   1  1  82902  82502
# 4 5678   2  2 288225 288224

答案 2 :(得分:1)

用于编码优雅(和一般效率)的data.table解决方案

如果您获得除第一行之外的任何行(并且每个子组中可能存在不同的行数),那么您将需要考虑当您尝试获取不存在的行时会发生什么。

以下解决方案将获得每个组的min(`n`, `total#of rows in each group`))

library(data.table)
DT <- data.table(sampleData)

# get the the row you want. This may 
#
index <- 2L
 DT[,{ idx <- min(index, .N); .SD[idx,]} ,by =list(SUBJ, BLK, TR)] 

答案 3 :(得分:0)

以下是针对一般情况的aggregate解决方案:

aggregate(. ~ SUBJ+BLK+TR, data=sampleData, FUN='[', 1)
##   SUBJ BLK TR    BEG    END
## 1 1234   1  1 111021 111021
## 2 5678   1  1  82503  82502
## 3 1234   2  2 132050 133113
## 4 5678   2  2 274870 288224


aggregate(. ~ SUBJ+BLK+TR, data=sampleData, FUN='[', 2)
##   SUBJ BLK TR    BEG    END
## 1 1234   1  1 111400 111021
## 2 5678   1  1  82902  82502
## 3 1234   2  2 133123 133113
## 4 5678   2  2 288225 288224

答案 4 :(得分:0)

在特定情况下(获取第一行或最后一行),您可以使用函数duplicated

sampleData[!duplicated(sampleData[,c("SUBJ","BLK","TR")],fromLast=FALSE),]