【问题标题】:Subsetting a Data Table using %in%使用 %in% 对数据表进行子集化
【发布时间】:2015-09-30 02:46:34
【问题描述】:

我的 data.table 的风格化版本是

outmat <- data.table(merge(merge(1:5, 1:5, all=TRUE), 1:5, all=TRUE))

我想做的是根据第一列中的值是否在任何其他列中找到,从此 data.table 中选择行的子集(它将处理未知维度的矩阵,所以我可以'不只是使用某种“row1 == row2 | row1 == row3”

我想使用

output[row1 %in% names(output)[-1], ]

但是如果在 row2 或 row3 的任何行中找到 row1 中的值,则最终返回 TRUE,这不是预期的行为。是否有某种矢量化版本的 %in% 可以达到我想要的结果?

详细地说,我想得到的是从集合 1:5 中枚举 3 元组,用替换绘制,使得第一个值与第二个或第三个值相同,例如:

1 1 1
1 1 2
1 1 3
1 1 4
1 1 5
...
2 1 2
2 2 1
...
5 5 5

我的代码给我的是 3 元组的每个枚举,因为它检查第一个数字(比如 5)是否出现在第二列或第三列的任何位置,而不仅仅是在同一行中。

【问题讨论】:

  • 我确实注意到我的原件中放错了 ) ,但我不熟悉 CJ 功能。我的目的是让示例枚举从 1 到 5 抽取的 3 个数字的所有组合,并进行替换。
  • 好的,刚刚注意到括号。你能根据输入数据显示预期的输出吗?因为你提到的比较令人困惑。
  • 我试图更清楚地解释所需的输出。用语言来解释要容易一些:枚举所有 N 掷骰子的序列,使得第一个掷骰的值至少重复一次。在我的示例中,N 为 3,但我希望它可以扩展,因此我有兴趣使用 %in% 的一些变体。

标签: r data.table


【解决方案1】:

一种选择是构造表达式并对其求值:

dt = data.table(a = 1:5, b = c(1,2,4,3,1), c = c(4,2,3,2,2), d = 5:1)
#   a b c d
#1: 1 1 4 5
#2: 2 2 2 4
#3: 3 4 3 3
#4: 4 3 2 2
#5: 5 1 2 1

expr = paste(paste(names(dt)[-1], collapse = paste0(" == ", names(dt)[1], " | ")),
             "==", names(dt)[1])
#[1] "b == a | c == a | d == a"

dt[eval(parse(text = expr))]
#   a b c d
#1: 1 1 4 5
#2: 2 2 2 4
#3: 3 4 3 3

另一种选择是循环并比较列:

dt[rowSums(sapply(dt, '==', dt[[1]])) > 1]
#   a b c d
#1: 1 1 4 5
#2: 2 2 2 4
#3: 3 4 3 3

【讨论】:

  • 只是想知道您的第一个解决方案,难道不能使用语言对象而不是解析字符来完成吗?
  • 我不完全确定你的意思。能举个例子吗?
  • 在符号和表达式上使用 callas.call 而不是在字符串上解析,但无法弄清楚这个例子
  • 我猜你可以用适当的元素构造一个列表来形成调用,但有什么意义呢?
  • 避免解析不太安全的字符串?
【解决方案2】:
library(dplyr)
library(tidyr)

dt %>%
  mutate(ID = 1:n() )
  gather(variable, value, -first_column, -ID) %>%
  filter(first_column == value) %>%
  select(ID) %>%
  distinct %>%
  left_join(dt)  

【讨论】:

    猜你喜欢
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多