2011-12-16 4 views
1

나는 이것에 대해 어떻게 생각하는지 꽤 혼란 스럽다. 데이터 프레임에 두 개의 열이 있다고 가정 해보십시오. 하나의 열은 숫자 계열을 순서대로 (x), 다른 하나는 첫 번째 열의 값을 지정하거나 -1 (y)를 지정합니다. 일치하는 실험의 결과입니다. 목표는 동일한 개인의 사진을 여러 장 찍는 것입니다. 아래의 예에서는 사진 10 장이 있지만 고유 한 인물은 6 장입니다. y 열에 일치하는 것이 있으면 해당 x가보고됩니다. 일치하지 않는 경우 y는 -1입니다 (NAs 일 수도 있음). 1 인당 2 장 이상의 사진이있는 경우 가장 최근의 기록이 일치합니다 (사진 1, 5 및 7은 아래의 동일한 개인). 그룹은 사진이 찍은 시간입니다 (그룹 내에서 일치하지 않습니다!). 다행스럽게도 필자는 바로이 예제를 가지고 :두 개의 열 비교 : 논리 - 열 2의 열 1의 값?

x <- c(1,2,3,4,5,6,7,8,9,10) 
y <- c(-1,-1,-1,-1,1,-1,1,-1,2,4) 
group <- c(1,1,1,2,2,2,3,3,3,3) 
DF <- data.frame(x,y,group) 

나는 독특한 개인의 이름을 수있는 새로운 변수를 생성하고, 각 당 하나의 행과 최종 데이터 집합을 가지고 싶습니다 (즉, 만 6 행 대신 열이), 그룹 정보도 포함됩니다. 나는. 한 개인이 세 그룹 모두에 있다면, "111"의 값이있을 수 있으며 첫 번째 그룹과 마지막 그룹에있는 경우 "101"이 될 수 있습니다. 어떤 팁?

결과 데이터 세트에 대해 문의 해 주셔서 감사합니다. 나는 실제 수치를 토대로 그룹 설명이 나빴다는 것을 깨달았으므로 결과를 조금 바 꾸었습니다. 보너스도 좋지만 중요한 것은 아닙니다.

name <- c(1,2,3,4,6,8) 
group_history <- as.character(c('111','101','100','011','010','001')) 
bonus <- as.character(c('1,5,7','2,9','3','4,10','6','8')) 
results_I_want <- data.frame(name,group_history,bonus) 

내 말은, 더 실수

+0

당신은 결과 데이터 집합이 예를 들어 어떻게 보이는지 추가 할 수 있습니다에 대한 또 다른 해결책은? –

답변

2

가 낮은 높은 숫자에서 매핑을 만들 수는

x <- c(1,2,3,4,5,6,7,8,9,10) 
y <- c(-1,-1,-1,-1,1,-1,1,-1,3,4) 
group <- c(1,1,1,2,2,2,3,3,3,3) 

DF <- data.frame(x,y,group) 

사용에게 xy 준 (업데이트) 예제를 사용하여 ... 위의 고정 같은 사람인 숫자. 이름은 숫자의 문자열 임에도 불구하고 문자열입니다. 우리는 낮은 숫자에 이르기까지 모든 것을 얻을 걸릴, 그래서 while 루프를 사용해야 할 수도 있습니다 얼마나 많은 시간을 모르는

bottom.df <- DF[DF$y==-1,] 
mapdown.df <- DF[DF$y!=-1,] 
mapdown <- c(mapdown.df$y, bottom.df$x) 
names(mapdown) <- c(mapdown.df$x, bottom.df$x) 

.

oldx <- DF$x 
newx <- mapdown[as.character(oldx)] 
while(any(oldx != newx)) { 
    oldx = newx 
    newx = mapdown[as.character(oldx)] 
} 

결과는 해당 그룹의 가장 낮은 수로 이름이 지정됩니다.

DF$id <- unname(newx) 

그룹 구성원 자격을 얻는 것이 어렵습니다. reshape2을 사용하여이를 와이드 형식 (그룹당 하나의 열)으로 변환합니다. 그 중 하나에 항목이있는 경우 열이 "1"이고 그렇지 않은 경우 "0"입니다.

library("reshape2") 

wide <- dcast(DF, id~group, value.var="id", 
       fun.aggregate=function(x){if(length(x)>0){"1"}else{"0"}}) 

마지막으로이 "0"/ "1"멤버십을 함께 붙여 넣어 설명 된 그룹화 변수를 가져옵니다.

wide$grouping = apply(wide[,-1], 1, paste, collapse="") 

결과 :

> wide 
    id 1 2 3 grouping 
1 1 1 1 1  111 
2 2 1 0 0  100 
3 3 1 0 1  101 
4 4 0 1 1  011 
5 6 0 1 0  010 
6 8 0 0 1  001 

아직 "보너스".

편집 :

는 보너스 정보를 얻으려면, 그것은 모든 것을 유지하기 위해 매핑을 다시 실행하는 데 도움이됩니다. 케이스가 많으면 느려질 수 있습니다.

oldx/newx 부분 교체 : 보너스 데이터를 생성하려면

iterx <- matrix(DF$x, ncol=1) 
iterx <- cbind(iterx, mapdown[as.character(iterx[,1])]) 
while(any(iterx[,ncol(iterx)]!=iterx[,ncol(iterx)-1])) { 
    iterx <- cbind(iterx, mapdown[as.character(iterx[,ncol(iterx)])]) 
} 

DF$id <- iterx[,ncol(iterx)] 

을, 당신은 사용할 수 있습니다

bonus <- tapply(iterx[,1], iterx[,ncol(iterx)], paste, collapse=",") 
wide$bonus <- bonus[as.character(wide$id)] 

:

> wide 
    id 1 2 3 grouping bonus 
1 1 1 1 1  111 1,5,7 
2 2 1 0 0  100  2 
3 3 1 0 1  101 3,9 
4 4 0 1 1  011 4,10 
5 6 0 1 0  010  6 
6 8 0 0 1  001  8 

참고이 ISN을 ' t 예제 출력과 같지만 예제 출력이 옳다고 생각하지 않습니다. (당신이 "000"의 grouping_history을 가질 수 있습니까?)

편집 :

는 이제 동의합니다.

+0

방금 ​​더 많은 실수를 수정했습니다 : ( – Nate

+0

운 좋게도 당신이 내 문제를 알아 냈기 전에 그것을 올바르게 설명했습니다. – Nate

1

보너스 변수

f_bonus <- function(data=df){ 
    data_a <- subset(data,y== -1,select=x) 
    data_a$pos <- seq(nrow(data_a)) 
    data_b <- subset(df,y!= -1,select=c(x,y)) 
    data_b$pos <- match(data_b$y, data_a$x) 
    data_t <- rbind(data_a,data_b[-2]) 
    data_t <- with(data_t,tapply(x,pos,paste,sep="",collapse=",")) 
    return(data_t) 
}