【问题标题】:Comparing two datasets using data.table使用 data.table 比较两个数据集
【发布时间】:2020-07-01 10:06:54
【问题描述】:

考虑以下数据集

data_00 <- data.table(ID = c(1,1,1,2,2,2,3,3,3,4,5,5,6), 
                COLOUR = c("blue","green","yellow","yellow","red","blue","green","green","white","green","blue","yellow","white"))

data_01 <- data.table(ID=c(1,2,2,2,3,3,4,4,5,6,6),
                COLOUR=c("red","blue","green","white","yellow","blue","white","green","blue","white","pink"))

  ID COLOUR
 1:  1   blue
 2:  1  green
 3:  1 yellow
 4:  2 yellow
 5:  2    red
 6:  2   blue
 7:  3  green
 8:  3  green
 9:  3  white
10:  4  green
11:  5   blue
12:  5 yellow
13:  6  white

    ID COLOUR
 1:  1    red
 2:  2   blue
 3:  2  green
 4:  2  white
 5:  3 yellow
 6:  3   blue
 7:  4  white
 8:  4  green
 9:  5   blue
10:  6  white
11:  6   pink

ID 代表一个人的身份,并为这个人的房间的墙壁颜色着色。我使用 data.table 包,因为真实数据非常大,因此需要一个高效的包。我想将 b 中所述的颜色与 a 中的颜色进行比较,调查特定家庭是否在前一年也有这种墙壁颜色,并在 data_01 中添加第三列,其中包含此问题的逻辑值。

我试过了

data_01 <- data_01[COLOUR00:=(COLOUR %in% data_00$ID[COLOUR]),by=ID]
but the logical values returned are wrong.

预期的输出应该是:

   ID COLOUR PREV_YEAR
 1:  1    red     FALSE
 2:  2   blue      TRUE
 3:  2  green     FALSE
 4:  2  white     FALSE
 5:  3 yellow     FALSE
 6:  3   blue     FALSE
 7:  4  white     FALSE
 8:  4  green      TRUE
 9:  5   blue      TRUE
10:  6  white      TRUE
11:  6   pink     FALSE

我想要一个额外的行来表明该颜色是否存在于前一年的家庭住宅中。 有人可以帮我解决这个问题吗?

【问题讨论】:

  • 您的预期输出是什么?也许你需要一些*_join(left_join)?或者使用 ifelse 和两个 ID 并将其添加到目标数据帧?
  • 预期的输出是什么,到目前为止的答案有两种不同的解释。
  • @NelsonGon,@sindri_baldur 我在问题中添加了预期的输出。
  • @clara_____ 为什么第 8 行不是 TRUE?
  • @哦,你说得对!

标签: r data.table compare comparison logical-operators


【解决方案1】:

一个非常简单的方法是:

data_01[, last_year := paste(ID,COLOUR) %chin% data_00[, paste(ID,COLOUR)]]

    ID COLOUR last_year
 1:  1    red     FALSE
 2:  2   blue      TRUE
 3:  2  green     FALSE
 4:  2  white     FALSE
 5:  3 yellow     FALSE
 6:  3   blue     FALSE
 7:  4  white     FALSE
 8:  4  green      TRUE
 9:  5   blue      TRUE
10:  6  white      TRUE
11:  6   pink     FALSE

使用连接:

data_01[, last_year := FALSE
        ][data_00, on = .(ID,COLOUR), last_year := TRUE]

【讨论】:

  • 如上所述 - 它有效!然而,我仍然难以理解你在这里究竟做了什么,你会费心解释一下吗?我对 R 比较陌生。
  • @clara_____ 我认为第一个解决方案更直接,我们将两列粘贴到一个中,然后使用 %in%%chin% 只是一个快速的替代方案)。第二种解决方案需要对 data.table 连接有所了解。
  • 我了解第一个解决方案,我只是想了解您在第二个解决方案中做了什么:)
  • @clara_____ 基本上,您可以将一个 data.table 与另一个具有匹配项的 data.table 子集。检查data_01[data_00, on = .(ID,COLOUR), nomatch = 0L]的结果。
【解决方案2】:

OP 的方法是检查data_01 中的颜色是否包含在相同ID 的上一年颜色的向量中。

对 OP 的代码进行一些修改,

data_01[, COLOR00 := COLOUR %in% data_00[.BY == ID, COLOUR], by = ID][]

返回预期结果:

    ID COLOUR COLOR00
 1:  1    red   FALSE
 2:  2   blue    TRUE
 3:  2  green   FALSE
 4:  2  white   FALSE
 5:  3 yellow   FALSE
 6:  3   blue   FALSE
 7:  4  white   FALSE
 8:  4  green    TRUE
 9:  5   blue    TRUE
10:  6  white    TRUE
11:  6   pink   FALSE

一些修改是由于 data.table 语法与基础 R data.frame 的差异。

但是,主要技巧是使用特殊符号.BY 来查找与ID 匹配的行。 .BY 是一个列表,其中包含实际组的 by = 子句中的项目。没有.BY,我们很想写

data_01[, COLOR00 := COLOUR %in% data_00[ID == ID, COLOUR], by = ID][]

这是模棱两可的,因为IDdata_00data_01 中的列名。

无论如何,sindri_baldur 建议的加入是一种更清洁的方式,恕我直言。

【讨论】:

    猜你喜欢
    • 2011-07-30
    • 2015-07-10
    • 2014-08-30
    • 1970-01-01
    • 2020-09-30
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    相关资源
    最近更新 更多