2017-11-25 26 views
-2

我正在处理员工数据。整个数据框有104列,但为此,我只关心两列。我们有一个员工编号和他们的主管(以员工编号列中存在的主管编号的形式)。我需要对数据进行排序,以便员工编号在管理员标识列中的任何实例上方。员工 - 主管排序R

下面是我的第一个解决方案,但它有几个问题,我认为有一个更好的方法来做到这一点。现在,它不仅仅是将行向上移动,而是添加一个新行,所以它永远不会完成。

任何援助将不胜感激。

library(iterators) 
EmpNo <- c(1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118) 
SupervisorID <- c(1118, 1117, 1114, 1112, 1112, 1118, 1117, 1117) 
supervisors <- data.frame(EmpNo, SupervisorID) 

loop <- TRUE 
while(loop) 
{ 
    loop <- FALSE 
    iSupervisor <- iter(supervisors, by ='row') 
    for(i in 1:nrow(supervisors)) 
    { 
    tempElem <- nextElem(iSupervisor) 
    if(nrow(tempElem) == 1) 
    { 
     # It does not properly move the row. 
     if(i > 1) 
     { 
     if(nrow(supervisors[tempElem$EmpNo %in% supervisors[1:(i-1),"SupervisorID"]]) > 0) 
     { 
      if(length(which(supervisors$SupervisorID == tempElem$EmpNo)) != 0) 
      { 
      sup.first <- min(which(supervisors$SupervisorID == tempElem$EmpNo)) 
      if(sup.first > i) 
      { 
       loop <- TRUE 
       if(i == nrow(supervisors)) 
       { 
       if(sup.first == 1) 
       { 
        supervisors <- rbind(supervisors[i,],supervisors[1:(i-1),]) 
       } else 
       { 
        supervisors <- rbind(supervisors[1:(sup.first-1),],supervisors[i,],supervisors[sup.first:(i-1),]) 
       } 
       } else 
       { 
       if(sup.first == 1) 
       { 
        supervisors <- rbind(supervisors[i,],supervisors[1:(i-1),], supervisors[(i+1):nrow(supervisors),]) 
       } else 
       { 
        supervisors <- rbind(supervisors[1:(sup.first-1),],supervisors[i,],supervisors[sup.first:nrow(supervisors),]) 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
    if(nrow(supervisors) > 50) { loop <- FALSE } 
    } 
    rownames(supervisors) <- NULL 
} 

更新: 有一个是主管。他们的SupervisorID与他们的EmpNo相同。员工编号的排序不相关,除了它必须高于向他们报告的任何人。以下是一些示例数据。

初始化数据:

 
EmpNo SupervisorID 
1111 1118 
1112 1117 
1113 1114 
1114 1112 
1115 1112 
1116 1118 
1117 1117 
1118 1117 

期望的结果:

 
EmpNo SupervisorID 
1117 1117 
1118 1117 
1112 1117 
1111 1118 
1116 1118 
1114 1112 
1115 1112 
1113 1114 

UPDATE: 更新了代码,使其完全可重复的,包括休息,防止其无限运行。

+2

我们可以有一个*小*可重现的例子吗? –

+0

监事有监事吗?在你想要的解决方案中,有没有人可以成为第一个?它必须是没有监督员的人。 – G5W

+0

是的,主管可以有主管,有一个是主管。我会添加一些示例数据。 –

回答

0

下面是我的解决方案。它仍然有点慢,但它解决了这个问题。

'%!in%' <- function(x,y)!('%in%'(x,y)) 

EmpNo <- c(1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118) 
SupervisorID <- c(1118, 1117, 1114, 1112, 1112, 1118, 1117, 1117) 
Status <- c('A','A','A','A','A','A','A','A') 
check <- c(1,2,3,4,5,6,7,8) 
supervisors <- data.frame(EmpNo, SupervisorID, Status, check, stringsAsFactors = FALSE) 

loop <- TRUE 
while(loop) 
{ 
    loop <- FALSE 
    supervisors$check <- apply(supervisors[,c('EmpNo', 'check', 'Status')], 1, function(y) { 
    if(y['Status'] %!in% c('T','N')){ 
     if(nrow(supervisors[y['EmpNo'] %in% supervisors[1:max(((as.numeric(y['check'])-1)),1),"SupervisorID"]]) > 0) 
     { 
     if(length(which(supervisors$SupervisorID == y['EmpNo'])) > 0) 
     { 
      sup.first <- min(which(supervisors$SupervisorID == y['EmpNo'])) 
      if(sup.first < as.numeric(y['check'])) 
      { 
      loop <<- TRUE 
      } 
      sup.first - 1 
     } else 
     { 
      nrow(supervisors) 
     } 
     } 

    } else { 
     nrow(supervisors) 
    } 
    }) 
    supervisors <- supervisors[order(supervisors$check),] 
    supervisors$check <- as.numeric(rownames(supervisors)) 
    rownames(supervisors) <- NULL 
}