r 中的双重匹配

Double match in r

我在 r 中有一个巨大的数据集,每个人一行。我的其中一列显示了一个家庭标识符(注意,sex==1,男性,sex==2,女性)。

ind sex income  hw  family.id
1   1    10     6    fam.1
2   2    8      7    fam.1
3   2    15     8    fam.2
4   1    7      4    fam.3
5   2    9      5    fam.3

我如何做 "double matching" 才能匹配数据集中我感兴趣的许多变量的情侣?例如,假设个人 2,女性,与个人 1,男性结婚,应该在一个新的列中收到一个条目,其中包含他的收入(hw 也是如此):

ind sex income  hw  family.id  income.male   hw.male
1   1    10     6    fam.1       10            6
2   2    8      7    fam.1       8             6
3   2    15     8    fam.2       -             -
4   1    7      4    fam.3       7             7  
5   2    9      5    fam.3       9             7

我在标题中说了"double matching",因为我不需要只匹配family.ID,但我需要找到一个匹配这个fam.id的男性。我这样做的原因是因为稍后所有男性将从数据集中删除,我将只保留女性行。

很抱歉,我无法显示我编写的任何代码。我尝试了很多使用 match、ifelselapply 甚至 unlist 的方法,但不值得在这里添加它,因为不幸的是我无法让它工作。

有人知道吗?我们可以同时使用 data.framesdata.tables 环境。

让我们假设数据框被命名为 'dat'。您可以通过 family.id 使用合并功能合并男性和女性。你提出的答案对我或其他评论者没有意义,但你可以在这个新对象中重新分配 "income" 或 "hw"。

> merge( dat[ dat$sex==1, ], dat[dat$sex==2,] , by="family.id")
  family.id ind.x sex.x income.x hw.x ind.y sex.y income.y hw.y
1     fam.1     1     1       10    6     2     2        8    7
2     fam.3     4     1        7    4     5     2        9    5

你应该使用 data.table 包。这是一个例子:

library(data.table)

dt <- data.table(ind = c(1, 2, 3, 4, 5), sex =c(1, 2, 2, 1, 2), income = c(10, 8, 15, 7, 9), hw = c(6, 7, 8, 4, 5), family.id = c('fam.1', 'fam.1', 'fam.2', 'fam.3', 'fam.3'))
setkeyv(dt, 'family.id')

dt2 <- dt[dt[sex == 1, list(family.id, income, hw)]]

它将需要 incomehw 的男性 (dt[sex == 1, list(family.id, income, hw)]) 并匹配 family.id 上的所有个体。结果您获得:

   ind sex income hw family.id i.income i.hw
1:   1   1     10  6     fam.1       10    6
2:   2   2      8  7     fam.1       10    6
3:   4   1      7  4     fam.3        7    4
4:   5   2      9  5     fam.3        7    4

前缀为 i. 的列包含每个家庭的男性值。请注意,如果没有男性在场,您将不会收到任何行。如果您仍然需要这个,您可以这样做:

dt2 <- merge(dt, dt[sex == 1, list(family.id, income, hw)], by = 'family.id', suffixes = c('', '.i'), all = TRUE)

接收

   family.id ind sex income hw income.i hw.i
1:     fam.1   1   1     10  6       10    6
2:     fam.1   2   2      8  7       10    6
3:     fam.2   3   2     15  8       NA   NA
4:     fam.3   4   1      7  4        7    4
5:     fam.3   5   2      9  5        7    4

稍后当您需要删除男性数据时:

dt2[sex == 2]

跟进我的

require(data.table)
dt[dt[sex == 1L], c("i.m", "hw.m") := .(i.income, i.hw), on="family.id"][]

为每个 family.id 提取 sex == 'male' 的行索引,并通过引用 添加两列 以及相应的 incomehw 值。


其中 dt 是:

dt = fread('ind sex income  hw  family.id
1   1    10     6    fam.1
2   2    8      7    fam.1
3   2    15     8    fam.2
4   1    7      4    fam.3
5   2    9      5    fam.3')