2013-04-01 1 views
3

동일한 ID 코드로 여러 항목을 평가하고 일련의 조건부가 충족되는 경우 마지막 행의 셀 값을 분할해야하는 데이터 세트가 있습니다. .셀의 값을 분할하고 R에서 새로 만든 행에 추가

Condtionals = 해당 ID의 마지막 행에는 동작 == "l"& 시간> 60이 있습니다.

이 조건이 충족되는 경우 행 동작 < - "e"를 변경하고 < - 60 시간을 변경하고 싶습니다. 60을 초과하는 시간은 새로 형성된 행 아래에 위치해야합니다. 새 행의 열 내용은 작업 == "l"& 시간 == 원본 값 - 60을 제외하고는 부모 행과 동일해야합니다.

샘플 데이터가

id <- c("12_1","12_1","12_1","12_2","12_2","12_2") 
action <- c("l","d","l","l","d","l") 
time <- c(15,45,90,20,30,61) 
dtfrm <-data.frame(cbind(id,action,time)) 

테스트 dataframe이

id action time 
1 12_1  l 15 
2 12_1  d 45 
3 12_1  l 90 
4 12_2  l 20 
5 12_2  d 30 
6 12_2  l 61 

나는 결국 내가 평가하는 더 복잡한 조건문이있을 것이다이

id action time 
1 12_1  l 15 
2 12_1  d 45 
3 12_1  e 60 
4 12_1  l 30 
5 12_2  l 20 
6 12_2  d 30 
7 12_2  e 60 
8 12_2  l 1 

처럼 보이도록 변환 dataframe을 원하는 설정하지만, 나는 더 복잡한 조건이 필요하기 때문에 간단하게 시작하려고 노력하고있다. 이 데이터 세트를 작업 순서로 마사지하십시오. 감사.

답변

3

내가 한 그룹 "ID"에 작동하는 기능을 작성합니다

process.one <- function(df) { 
    n <- nrow(df) 
    last.action <- df$action[n] 
    last.time <- df$time[n] 
    if (last.action == "l" & last.time > 60) { 
    next.row <- df[n, ] 
    next.row$action = "l" 
    next.row$time = last.time - 60 
    df <- rbind(df, next.row) 
    df$action[n] <- "e" 
    df$time[n] <- 60 
    } 
    df 
} 

그런 다음 슬릿을/ plyr를 사용하여 결합/적용

ddply(dtfrm, "id", process.one) 
#  id action time 
# 1 12_1  l 15 
# 2 12_1  d 45 
# 3 12_1  e 60 
# 4 12_1  l 30 
# 5 12_2  l 20 
# 6 12_2  d 30 
# 7 12_2  e 60 
# 8 12_2  l 1 

을 또한 확인하십시오 data.frame하지 않는 확인 그렇지 않으면 추가되는 요소가 문제가 될 수 있습니다. 상단에, 그것은해야한다 :

dtfrm <- data.frame(id, action, time, stringsAsFactors = FALSE) 
+0

감사합니다. 내 실제 데이터 프레임에는 46 개의 열이 있습니다. 이전 행의 모든 ​​값을 "복사"하고 작업 및 시간 만 변경하는 방법이 있습니까? 아니면 이러한 추가 열 이름을 추가해야하고 어떻게 수식에 채워 넣을 수 있습니까? – marcellt

+0

@marcellt, 맞습니다. 나는 나의 대답을 편집했다. – flodel

+0

감사합니다. 나는이 시작으로 당신의 답을 수정하고 추가 조건부에서 일할 수 있다고 생각했지만 약간의 문제가 있습니다. 위의 행을 평가하고 해당 행 동작이 == "d"인 경우에만 수정해야합니다. 나는 previous.action <-df $ action_time [n-1]을 만들 수 있고, 또 다른 & previous.action == "d"를 조건에 추가 할 수 있다고 생각했지만 작동하지 않습니다. 팁? – marcellt

2

이 참여 약간,하지만이 그것을 수행해야합니다 답장을

# fix the time column, it should be numeric 
dtfrm[, "time"] <- as.numeric(as.character(dtfrm[, "time"])) 

library(data.table) 
DT <- data.table(cbind(dtfrm, rowid=seq(nrow(dtfrm))), key="id") 

# identify which rows need modification 
DT[, needsMod := FALSE] 
DT[unique(DT[, "id", with=FALSE]) 
    , needsMod := {L <- length(action); (action[L] == "l" && time[L] > 60) } 
    , by=id 
    , mult="last"] 

# append new rows 
DT <- setkey(rbind(DT, 
     DT[c(needsMod), list(id, action, time=time-60, rowid=rowid+1e-2, needsMod=!needsMod)]), 
     id, rowid) 

# modify the identified rows 
DT[c(needsMod), c("action", "time") := list("e", 60)] 

# optionally remove added columns, though personally, I would keep some form of rowid 
DT[ , c("needsMod", "rowid") := NULL] 
DT 

#  id action time 
# 1: 12_1  l 15 
# 2: 12_1  d 45 
# 3: 12_1  e 60 
# 4: 12_1  l 30 
# 5: 12_2  l 20 
# 6: 12_2  d 30 
# 7: 12_2  e 60 
# 8: 12_2  l 1