2013-09-13 3 views
1

Моя проблема заключается в следующем:Как установить переменные одного наблюдения к другому в пределах того же набора данных в R

Предположим, что у меня есть набор данных, человеко-лет с информацией о семейном положении (cStatus), расы, год , супруг (PID) и город проживания:

data<-data.frame(cbind(c(rep(1,5),rep(2,5),rep(3,5),rep(4,5),rep(5,5)),c(rep(c(1,2,3,4,5),5)),c(NA,NA,NA,NA,NA,NA,NA,3,3,NA,NA,NA,2,2,7,6,6,6,6,6,NA,NA,NA,NA,NA),c(0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0),c(1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1),c(rep(1,5),rep(1,2),rep(2,3),rep(2,4),1,rep(1,5),rep(1,5)))) 
names(data)<- c("id","year","pID","cStatus","race","city") 

> head(data) 
id year pID cStatus race city 
1 1 NA  0 1 1 
1 2 NA  0 1 1 
1 3 NA  0 1 1 
1 4 NA  0 1 1 
1 5 NA  0 1 1 
2 1 NA  0 1 1 

Я хочу создать переменную для расы супруга (práce) для каждого наблюдения. Я пытаюсь сделать это для данного наблюдения «А», выполнив поиск в наборе данных для других наблюдений «В», который «id» имеет то же значение, что и «ПИД» наблюдения «А» и назначает «расу» «В», к «P».

Я думал о зацикливание:

for(i in unique(data$id)){ 
    data[data$id==i,]$pRace <-ifelse(data[data$id==i,]$cStatus==1,data[data$id==data[data$id==i,]$pID,]$race,NA) 
} 

Это, помимо того, что очень некрасиво, урожаи:

Warning messages: 
1: In `[<-.data.frame`(`*tmp*`, data$id == i, , value = list(id = c(1, : 
    provided 8 variables to replace 7 variables 

Есть ли способ сделать это правильно? Правильно ли я пытаюсь использовать петли?

+0

Похоже, вам просто нужно использовать 'merge'. – joran

+0

@joran Энди предложил это как ответ там. Это работает, но у меня есть случаи, когда люди меняли партнеров, и я хотел бы иметь гонку партнера в конкретном году. – Kenji

+1

Вы можете объединить несколько переменных. 'merge' выполняет примерно ту же функциональность, что и SQL-соединения. – joran

ответ

3
# create a dataframe that has unique entries for each person and their race 
spouses <- unique(data[c("id", "race")]) 
names(spouses) <- c("pID", "pRace") 

# merge race via spouse id 
data <- merge(data, spouses, by="pID", all.x=TRUE) 

Что дает:

> data 
    pID id year cStatus race city pRace 
1 2 3 4  1 0 2  1 
2 2 3 3  1 0 2  1 
3 3 2 4  1 1 2  0 
4 3 2 3  1 1 2  0 
5 6 4 2  1 0 1 NA 
6 6 4 1  1 0 1 NA 
7 6 4 3  1 0 1 NA 
8 6 4 5  1 0 1 NA 
9 6 4 4  1 0 1 NA 
10 7 3 5  1 0 1 NA 
11 NA 1 1  0 1 1 NA 
12 NA 1 2  0 1 1 NA 
[...] 

Уведомление вы получите NA, где либо pID не само по себе не существует в данных (не соответствующих id) или там, где нет супруга.

Если вы хотите учитывать меняющихся супругов в течение многих лет, просто добавьте годы как к вспомогательному фреймворку, так и к аргументам merge. Как @joran указывает, merge может принимать несколько столбцов, чтобы объединиться, подобно SQL.

# create a dataframe that has unique entries for each person and their race 
spouses.yearly <- unique(data[c("id", "year", "race")]) 
names(spouses.yearly) <- c("pID", "pRace") 

# merge race via spouse id 
data <- merge(data, spouses.yearly, by=c("pID", "year"), all.x=TRUE) 
Смежные вопросы