Q:

Match household partners without loop

I am trying to avoid using a loop in my attempt to recode household partners' variable identification. 
hldid denotes the household while persid the person in the household. 
The variable partner indicates the persid of the partner and child indicate if the row is a child. 
What is missing from the variable partner is the persid for both partners. 
For instance for hldid == 1, the persid == 1 has a value of 0 for partner while it should be 2. 
This is how the data looks like:
> test
   hldid persid age sex relresp partner child
1      1      1  26   2       0       0     0
2      1      2  26   1       1       1     0
3      2      1  59   2       0       0     0
4      2      2  64   1       1       1     0
5      3      1  76   2       0       0     0
6      4      1  65   2       0       0     0
7      4      2  64   1       1       1     0
8      5      1  52   2       0       0     0
9      5      2  51   1       1       1     0
10     5      3  20   2      21       0     1
11     5      4  14   2      21       0     1
12     7      1  69   1       0       0     0
13     7      2  70   2       1       1     0

I managed to create a quite ugly loop, however it is too slow for the entire dataset. 
test$partnerREC = test$partner

for(i in 1:13){
  for(j in 1:13){

    if(
      test$hldid[i] == test$hldid[i+1] & # verify if household is the same 
      (test$persid[i] == test$partner[j])
    )

    {
      test$partnerREC[i] = test$persid[j] # put the persid for each partner
    }
  }
}

> test
   hldid persid age sex relresp partner child partnerREC
1      1      1  26   2       0       0     0          2
2      1      2  26   1       1       1     0          1
3      2      1  59   2       0       0     0          2
4      2      2  64   1       1       1     0          1
5      3      1  76   2       0       0     0          0
6      4      1  65   2       0       0     0          2
7      4      2  64   1       1       1     0          1
8      5      1  52   2       0       0     0          2
9      5      2  51   1       1       1     0          1
10     5      3  20   2      21       0     1          0
11     5      4  14   2      21       0     1          0
12     7      1  69   1       0       0     0          2
13     7      2  70   2       1       1     0          1 

Any idea how I could use data.table for solving this? 
test = structure(list(hldid = c(1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 5, 7, 
7), persid = c(1, 2, 1, 2, 1, 1, 2, 1, 2, 3, 4, 1, 2), age = c(26, 
26, 59, 64, 76, 65, 64, 52, 51, 20, 14, 69, 70), sex = c(2, 1, 
2, 1, 2, 2, 1, 2, 1, 2, 2, 1, 2), relresp = c(0, 1, 0, 1, 0, 
0, 1, 0, 1, 21, 21, 0, 1), partner = c(0, 1, 0, 1, 0, 0, 1, 0, 
1, 0, 0, 0, 1), child = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 
0)), class = "data.frame", row.names = c(NA, -13L))

A:

A possible solution:
library(data.table)  # load the package
setDT(test)          # convert 'test' to a 'data.table'

test[, partnerREC := persid[c(pmin(2,.N):1,rep(0,(pmax(.N,2)-2)))] *
                       (persid %in% 1:2) *
                       (.N != 1)
     , by = hldid][]

which gives:

> test
    hldid persid age sex relresp partner child partnerREC
 1:     1      1  26   2       0       0     0          2
 2:     1      2  26   1       1       1     0          1
 3:     2      1  59   2       0       0     0          2
 4:     2      2  64   1       1       1     0          1
 5:     3      1  76   2       0       0     0          0
 6:     4      1  65   2       0       0     0          2
 7:     4      2  64   1       1       1     0          1
 8:     5      1  52   2       0       0     0          2
 9:     5      2  51   1       1       1     0          1
10:     5      3  20   2      21       0     1          0
11:     5      4  14   2      21       0     1          0
12:     7      1  69   1       0       0     0          2
13:     7      2  70   2       1       1     0          1

This solution is based on the assumption (derived from the example data) that only 'persid' 1 & 2 are partners, anything higher are children.
What this does:

Group by hldid
Change the order of the first two persons in a hould but only when there are more people in a household with
persid[c(pmin(2,.N):1,rep(0,(pmax(.N,2)-2)))] where pmin is used to assure that a vector of length 1 is constructed when a household has only one person.
Multiply that with (persid %in% 1:2)to get zores for children.
Multiply that with (.N != 1) to get a value of zero for households of one person.

