【问题标题】:matching two data frames and change values in one of the data frames匹配两个数据帧并更改其中一个数据帧中的值
【发布时间】:2016-07-01 19:28:12
【问题描述】:

我有两个数据框。下面给出了可重现的例子:

structure(list(`1` = c(0L, 1L, 1L), `2` = c(1L, 0L, -1L), `3` = c(0L, 
0L, 0L), `4` = c(0L, 0L, 0L), `5` = c(0L, 0L, 0L), `6` = c(0L, 
0L, 0L), `7` = c(0L, -1L, 0L), `8` = c(0L, 0L, 0L), `9` = c(0L, 
0L, 0L), `10` = c(0L, 0L, 0L), `11` = c(0L, 0L, 0L), `12` = c(0L, 
0L, 0L), `13` = c(0L, 0L, 0L), `14` = c(0L, 0L, 0L), `15` = c(0L, 
0L, 0L), `16` = c(0L, 0L, 0L), `17` = c(0L, 0L, 0L), `18` = c(0L, 
0L, 0L), `19` = c(0L, 0L, 0L), `20` = c(0L, 0L, 0L), `21` = c(0L, 
0L, 0L), `22` = c(0L, 0L, 0L), `23` = c(0L, 0L, 0L), `24` = c(-1L, 
0L, 0L)), .Names = c("1", "2", "3", "4", "5", "6", "7", "8", 
"9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", 
"20", "21", "22", "23", "24"), row.names = c(3L, 6L, 12L), class = "data.frame")

这有 24 列,每列代表语句。第二个数据框如下:

structure(list(Level = c(1L, 1L, 1L, 1L), Statement = c("attr1", 
"attr2", "attr24", "attr7"), StmtNo = c(1L, 2L, 24L, 7L)), .Names = c("Level", 
"Statement", "StmtNo"), row.names = c(NA, 4L), class = "data.frame")

第二个数据框有一列名为 StmtNo。这是 df1 中列的对应编号。例如,DF2 中的 StmtNo 1,与 DF1 的第 1 列匹配。

我想做的是:

对于 DF1 中值为 0 的所有单元格,我必须将 DF1 中的列号与 DF2 的 StmtNo 列匹配。如果列号匹配,则单元格值应为 0,如果不匹配,则值应为 NA。我尝试将 apply 与 if 条件一起使用:

df1 <- apply(df1, function(x) if (x == 0) {
    if (exists(colnames(df1)) %in% df2$StmtNo) {
        x == NA
    } else {
        x == 0
    } 
})

但这会返回一个逻辑列表。我想要的输出如下:

   1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
3  0  1 NA NA NA NA  0 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA -1
6  1  0 NA NA NA NA -1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA  0
12 1 -1 NA NA NA NA  0 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA  0

虽然以上在填写 NA 方面可能看起来很统一,但我有 60 个这样的文件,每个文件都有需要填写 NA 的不同列。

【问题讨论】:

  • 你的意思是StmtNo列中的所有值都应该保持在df1中,如果零应该更改为NA,则其余的值?
  • 否,df2$StmtNo 中的值与 df1 中的列号匹配。因此,如果特定列的 DF1 中的单元格值为零,那么我需要检查该特定列号是否在 df2$StmtNo 中可用。如果它可用,那么我必须将其保留为零,如果它不可用,则我需要将其更改为 NA。我给出的期望输出在 DF1 中的第 3 列具有 NA。这意味着 df2$StmtNo 中没有 3。
  • 是的,df2$StmtNo 的值是 1、2、24、7,这些列在 df1 中保留了它们的值,其余的都转换为 NA

标签: r match


【解决方案1】:

一种不太优雅的蛮力方法

cols <- names(df1)[!names(df1) %in% df2$StmtNo]
df <- data.frame( matrix(NA, ncol = length(cols), nrow = 3) )
names(df) <- cols
df <- cbind(df, df1[, df2$StmtNo])

df[, order(as.numeric(names(df)))]

#    1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# 3  0  1 NA NA NA NA  0 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA -1
# 6  1  0 NA NA NA NA -1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA  0
# 12 1 -1 NA NA NA NA  0 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA  0

【讨论】:

  • df1[!names(df1) %in% df2$StmtNo] &lt;- NAreplace(df1, !names(df1) %in% df2$StmtNo, NA) 作为简化。
  • 谢谢 Symbolix。这很聪明!我被 60 多个数据集所困,并试图一次性为所有这些数据集找到解决方案……这很有帮助。
  • @RonakShah - 那么可能是df1[!names(df1)[col(df1)] %in% df2$StmtNo &amp; df1==0] &lt;- NA
  • @thelatemail - 它们确实是更好/更优雅的解决方案。您应该将它们添加为答案
  • @LeArNr 不客气。但是,您应该考虑 thelatemail 的建议,因为它们比我的更好
【解决方案2】:

这里尝试使用data.frame 对象的一些索引。 基本选择返回:

!names(df1)[col(df1)] %in% df2$StmtNo & df1==0
#       1     2    3    4    5    6     7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23    24
#3  FALSE FALSE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
#6  FALSE FALSE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
#12 FALSE FALSE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE

这意味着你可以做到:

df1[!names(df1)[col(df1)] %in% df2$StmtNo & df1==0] <- NA
df1

#   1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#3  0  1 NA NA NA NA  0 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA -1
#6  1  0 NA NA NA NA -1 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA  0
#12 1 -1 NA NA NA NA  0 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA  0

【讨论】:

    猜你喜欢
    • 2018-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 2021-03-10
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多