【问题标题】:R - Compare column values in data frames of differing lengths by unique IDR - 通过唯一 ID 比较不同长度的数据帧中的列值
【发布时间】:2017-05-30 09:38:26
【问题描述】:

我确信我可以找到一个简单的解决方案来解决这个问题,但我没有看到类似的问题,所以我想我会发布一个问题。

我有一个纵向数据集,其中包含多个时间间隔内的数千名受访者。从问题到数据类型的所有内容都可能因波而异,并且通常需要构建长系列的布尔值来构建指标或虚拟变量,但每个受访者都有一个唯一的 ID,在第一波之后没有额外的受访者添加到调查中,所以很容易够了。

问题在于,虽然早期的每一波都包含一个(Stata)文件,但后一波包含大量的附录文件,结构不同。因此,例如,在为先前合作伙伴的性别构建先前的指标时,有名为 partnerNum 和 sex 的列(用于一个波),每个唯一 ID(受访者)最多有 16 行。很容易传播(或强制转换)该数据,以便能够为每个唯一 ID 和列 partnerNum_1 ... partnerNum_16 创建一行,并将性别列中的值作为 partnerDF 中的条目。然后很容易构建如下指标:

sexuality$newIndicator[mainDF$bioSex = "Male" & apply(partnerDF[1:16] == "Male", 1, any)] <- 1

对于最后两波中的其他附录文件,数据的结构很长,就像合作伙伴数据一样,每个唯一 ID 有多行,但不仅仅是像性别这样的一个变量,我需要使用数百个变量来进行测试构造指标,全部用不同的类型编码,因此将数据广泛传播(或强制转换)是不切实际的(更不用说写那些布尔值了)。实际上,每一波都有几个这样的文件,它们的结构方式一些受访者(唯一 ID)只占 1 行,几十个。 (我已经将每一波的附录文件一起 left_join 了。)

我想做的就是测试类似的东西:

newDF$indicator[any(waveIIIAdds$var1 == 1) & any(waveIIIAdds$var2 == 1)] <- 1

newDF$indicator[mainDF$var1 == 1 & any(waveIIIAdds$var2 == 1)] <- 1

其中 newDF 与 mainDF 长度相同(每个唯一 ID 一行)。

例如,如果我有两个 dfs。

df1 <- data.frame(ID = c(1:4), A = rep("a"))
df2 <- data.frame(ID = rep(1:4, each=2), B = rep(1:2, 2), stringsAsFactors = FALSE)
df1$A[1] <- "b"
df1$A[3] <- "b"
df2$B[8] <- 3

> df1   > df2
ID A    ID B
1  b    1  1
2  a    1  2
3  b    2  1
4  a    2  2
        3  1
        3  2
        4  1
        4  3

我想测试一下(假设 df3 有一列,只有来自 df1 的唯一 ID)

df3$new <- 0
df3$new[df1$ID[df1$A == "a"] & df2$ID[df2$B == 2]] <- 1

因此 df3 每行将有一个唯一 ID,并且由于所有 ID 在 df1$A 中都有一个“a”,但对于所有 ID,df1$A[1] 和至少一行 df2$B 中有一个 2除了最后一个 ID (df2$B[7:8]),结果将是:

> df3
ID new
1  0
2  1
3  1
4  0

df3$new <- 0
df3$new[df1$ID[df1$A == "a"] | df2$ID[df2$B == 2]] <- 1

> df3
ID new
1  1
2  1
3  1
4  0

【问题讨论】:

    标签: r dataframe compare comparison multiple-columns


    【解决方案1】:

    这样就可以了……

    df3 <- data.frame(ID=unique(df1$ID),
                      new=sapply(unique(df1$ID),function(x) 
                         as.numeric(x %in% df1$ID[df1$A == "a"] & x %in% df2$ID[df2$B == 2])))
    
    df3
      ID new
    1  1   1
    2  2   1
    3  3   1
    4  4   0
    

    【讨论】:

    • 这适用于示例,但不适用于实际数据。我可以想到一个例子,虽然这会使数据集的构建变得更容易!谢谢!
    【解决方案2】:

    我想出了一个简洁的解决方案,在返回问题后几分钟(而不是帖子的凌晨)。

    我想要一个可能会以这种方式构建数千个指标或虚拟变量并且可能首先学习 R 甚至只学习 R 的研究生可以使用的东西。下面提供了示例和实际数据使用相同架构的解决方案:

    如果已经创建了 DF,并且虚拟指标的列值已经按照示例中的假设初始化为零:

    df3 <- data.frame(ID = df1$ID)
    df3$new <- 0
    

    我的解决方案是:

    df3$new[df1$ID %in% df1$ID[df1$A == "a"] & df1$ID %in% df2$ID[df2$B == 2]] <- 1 
    
    > df3
    ID new
    1   0
    2   1
    3   0
    4   1
    

    使用 | (或)改为:

    df3$new[df1$ID %in% df1$ID[df1$A == "a"] | df1$ID %in% df2$ID[df2$B == 2]] <- 1 
    
    > df3
    ID new
    1   1
    2   1
    3   0
    4   1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-12
      • 1970-01-01
      相关资源
      最近更新 更多