R枚举具有唯一值

时间:2015-09-04 08:45:47

标签: r duplicates

我有一个包含一组部件和测试结果的数据框。这些部件在3个站点(北中心和南部)进行测试。有时这些部件会重新测试。我想最终创建一些图表,比较第一次测试部件的结果与测试部件的第二次(或第三次等)时间的结果。看看测试仪的可重复性。

举个例子,我提出了以下代码。 我已经明确删除了"实验"来自morley数据集的列,因为这是我有效地尝试重新创建的列。代码有效,但似乎必须有更优雅的方法来解决这个问题。有什么想法吗?

编辑 - 我意识到给出的例子对我的实际需求过于简单(我试图尽可能容易地生成可重现的例子)。

新例子:

part<-as.factor(c("A","A","A","B","B","B","A","A","A","C","C","C"))
site<-as.factor(c("N","C","S","C","N","S","N","C","S","N","S","C"))
result<-c(17,20,25,51,50,49,43,45,47,52,51,56)

data<-data.frame(part,site,result)
data$index<-1
repeat {
    if(!anyDuplicated(data[,c("part","site","index")]))
    { break }
    data$index<-ifelse(duplicated(data[,1:2]),data$index+1,data$index)
}
data

      part site result index
1     A    N     17     1
2     A    C     20     1
3     A    S     25     1
4     B    C     51     1
5     B    N     50     1
6     B    S     49     1
7     A    N     43     2
8     A    C     45     2
9     A    S     47     2
10    C    N     52     1
11    C    S     51     1
12    C    C     56     1

旧例子:

#Generate a trial data frame from the morley dataset
df<-morley[,c(2,3)]

#Set up an iterative variable
#Create the index column and initialise to 1
df$index<-1

# Loop through the dataframe looking for duplicate pairs of
# Runs and Indices and increment the index if it's a duplicate
repeat {
    if(!anyDuplicated(df[,c(1,3)]))
    { break }
    df$index<-ifelse(duplicated(df[,c(1,3)]),df$index+1,df$index)
}

# Check - The below vector should all be true
df$index==morley$Expt

3 个答案:

答案 0 :(得分:3)

我们可以在“运行”列上使用diffcumsum来获得预期的输出。在这种方法中,我们不是创建一个1s的列,即'index',并且假设'Run'中的序列是按照OP的例子中的顺序排序的。

indx <- cumsum(c(TRUE,diff(df$Run)<0))
identical(indx, morley$Expt)
#[1] TRUE

或者我们可以使用ave

indx2 <- with(df, ave(Run, Run, FUN=seq_along))
identical(indx2, morley$Expt)
#[1] TRUE

更新

使用新示例

with(data, ave(seq_along(part), part, site, FUN=seq_along))
#[1] 1 1 1 1 1 1 2 2 2 1 1 1

或者我们可以使用getanID

中的library(splitstackshape)
library(splitstackshape)
getanID(data, c('part', 'site'))[]

答案 1 :(得分:2)

您实际data.frame的详细信息可能很重要。但是,有几个选项可以用于您的示例:

#this works if each group starts with 1:
df$index<-cumsum(df$Run==1)
#this is maybe more general, with data.table
require(data.table)
dt<-as.data.table(df)
dt[,index:=seq_along(Speed),by=Run]

答案 2 :(得分:2)

我认为这是make.unique的工作,有一些操纵。

index <- 1L + as.integer(sub("\\d+(\\.)?","",make.unique(as.character(morley$Run))))
index <- ifelse(is.na(index),1L,index)
identical(index,morley$Expt)
[1] TRUE