我有一个包含一组部件和测试结果的数据框。这些部件在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
答案 0 :(得分:3)
我们可以在“运行”列上使用diff
和cumsum
来获得预期的输出。在这种方法中,我们不是创建一个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