通过对每行的值的函数过滤行,data.table

2024-03-06

从 data.frame 语法切换到 data.table 语法对我来说仍然不顺利。我以为下面的事情应该是微不足道的,但事实并非如此。我在这里做错了什么:

> DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9)
> DT
   x y v
1: a 1 1
2: a 3 2
3: a 6 3
4: b 1 4
5: b 3 5
6: b 6 6
7: c 1 7
8: c 3 8
9: c 6 9

我想要这样的东西:

cols = c("y", "v") # a vector of column names or indexes
DT[rowSums(cols) > 5] # Take only rows where
# values at colums y and v satisfy a condition. 'rowSums' here is just an
# example it can be any function that return TRUE or FALSE when applied 
# to values of the row. 

这可行,但是如果我想提供动态列名称怎么办?我的表格有很多列?

>DT[eval( quote(y + v > 5))] #and the following command gives the same result
> DT[y + v > 5]
   x y v
1: a 6 3
2: b 3 5
3: b 6 6
4: c 1 7
5: c 3 8
6: c 6 9
> DT[lapply(.SD, sum) > 5, .SDcols = 2:3] # Want the same result as above
Empty data.table (0 rows) of 3 cols: x,y,v
> DT[lapply(.SD, sum) > 5, ,.SDcols = 2:3]
Empty data.table (0 rows) of 3 cols: x,y,v
> DT[lapply(.SD, sum) > 5, , .SDcols = c("y", "v")]
Empty data.table (0 rows) of 3 cols: x,y,v

回答完后更新因为事实证明有很多方法可以做到这一点,所以我想看看哪种需求表现最好。以下是模拟时序代码:

nr = 1e7
DT = data.table(x=sample(c("a","b","c"),nr, replace= T),
                y=sample(2:5, nr, replace = T), v=sample(1:9, nr, T))
threshold = 5
cols = c("y", "v")
col.ids = 2:3
filter.methods = 'DT[DT[, rowSums(.SD[, cols, with = F]) > threshold]]
DT[DT[, rowSums(.SD[, col.ids, with = F]) > threshold]]
DT[DT[, rowSums(.SD) > threshold, .SDcols = cols]]
DT[DT[, rowSums(.SD) > threshold, .SDcols = c("y", "v")]]
DT[DT[, rowSums(.SD) > threshold, .SDcols = col.ids]]
DT[ ,.SD[rowSums(.SD[, col.ids, with = F]) > threshold]]
DT[ ,.SD[rowSums(.SD[, cols, with = F]) > threshold]]
DT[, .SD[rowSums(.SD) > threshold], .SDcols = cols, by = x]
DT[, .SD[rowSums(.SD) > threshold], .SDcols = col.ids, by = x]
DT[, .SD[rowSums(.SD) > threshold], .SDcols = c("y", "v"), by = x]
DT[Reduce(`+`,eval(cols))>threshold]
DT[Reduce(`+`, mget(cols)) > threshold]
'
fm <- strsplit(filter.methods, "\n")
fm <- unlist(fm)
timing = data.frame()
rn = NULL
for (e in sample(fm, length(fm))) { 
  # Seen some weird pattern with first item in 'fm', so scramble it
  rn <- c(rn, e)
  if (e == "DT[Reduce(`+`,eval(cols))>threshold]") {
    cols = quote(list(y, v))
  } else {
    cols = c("y", "v")
  }
  tm <- system.time(eval(parse(text = e)))
  timing <- rbind(timing, 
                  data.frame(
                    as.list(tm[c("user.self", "sys.self", "elapsed")])
                    )
                  )
}
rownames(timing) <- rn
timing[order(timing$elapsed),]

### OUTPUT ####
#                                                                     user.self sys.self elapsed
# DT[Reduce(`+`,eval(cols))>threshold]                                   0.416    0.168   0.581
# DT[Reduce(`+`, mget(cols)) > threshold]                                0.412    0.172   0.582
# DT[DT[, rowSums(.SD) > threshold, .SDcols = cols]]                     0.572    0.316   0.889
# DT[DT[, rowSums(.SD) > threshold, .SDcols = col.ids]]                  0.568    0.320   0.889
# DT[DT[, rowSums(.SD) > threshold, .SDcols = c("y", "v")]]              0.576    0.316   0.890
# DT[ ,.SD[rowSums(.SD[, col.ids, with = F]) > threshold]]               0.648    0.404   1.052
# DT[DT[, rowSums(.SD[, cols, with = F]) > threshold]]                   0.688    0.368   1.052
# DT[DT[, rowSums(.SD[, col.ids, with = F]) > threshold]]                0.612    0.440   1.053
# DT[ ,.SD[rowSums(.SD[, cols, with = F]) > threshold]]                  0.692    0.368   1.058
# DT[, .SD[rowSums(.SD) > threshold], .SDcols = c("y", "v"), by = x]     0.800    0.448   1.248
# DT[, .SD[rowSums(.SD) > threshold], .SDcols = col.ids, by = x]         0.836    0.412   1.248
# DT[, .SD[rowSums(.SD) > threshold], .SDcols = cols, by = x]            0.836    0.416   1.249

所以速度方面的冠军是:

DT[Reduce(`+`,eval(cols))>threshold]
DT[Reduce(`+`, mget(cols)) > threshold]

我更喜欢我的那个mget。我认为其他人速度较慢的原因是他们打电话rowSums, 然而Reduce只有助于形成表达式。衷心感谢所有给出答案的人。我很难决定选择“接受”答案。Reduce-based 对此非常具体sum操作,同时rowSums-based 是使用任意函数的示例。


cols = c("y", "v")

Try

DT[DT[, rowSums(.SD[, ..cols]) > 5]]

Or

DT[DT[, rowSums(.SD[, 2:3]) > 5]]

Or

DT[DT[, rowSums(.SD) > 5, .SDcols = cols]]

Or

DT[DT[, rowSums(.SD) > 5, .SDcols = c("y", "v")]]

Or

DT[DT[, rowSums(.SD) > 5, .SDcols = 2:3]]

Or

DT[ ,.SD[rowSums(.SD[, 2:3]) > 5]]

Or

DT[ ,.SD[rowSums(.SD[, ..cols]) > 5]]

Or

DT[, .SD[rowSums(.SD) > 5], .SDcols = cols, by = x]

Or

DT[, .SD[rowSums(.SD) > 5], .SDcols = 2:3, by = x]

Or

DT[, .SD[rowSums(.SD) > 5], .SDcols = c("y", "v"), by = x]

每一个都会导致

#    x y v
# 1: a 6 3
# 2: b 3 5
# 3: b 6 6
# 4: c 1 7
# 5: c 3 8
# 6: c 6 9

一些解释:

  1. .SD也是一个data.table可以在其中操作的对象DT scope; ..cols查看上方的调用框架[]它的用途是cols对象选择列。因此, 这条线DT[ ,rowSums(.SD[, ..cols]) > 5]将返回一个逻辑向量,指示在哪些情况下DT has y + v > 5。所以我们将添加另一个DT为了在范围内选择这个索引DT

  2. 当你使用.SDcols,它会缩小.SD仅针对这些列。因此,如果你只做类似的事情DT[, .SD[rowSums(.SD) > 5], .SDcols = 2:3],你将失去x列,因此by = x加入。

  3. 使用时的另一个选择.SDcols就是返回一个逻辑向量,然后将其嵌入到另一个逻辑向量中DT

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过对每行的值的函数过滤行,data.table 的相关文章

  • 汇总表中各列的字符值比例

    在这种数据框中 df lt data frame w1 c A A B C A w2 c C A A C C w3 c C A B C B 我需要计算所有列中字符值的列内比例 有趣的是 以下代码适用于大型实际数据集 但对上述玩具数据会引发错
  • 如何设置 jQuery DataTables 中特定列的最大宽度

    如何设置一个特定列的最大宽度 所有其他列应自动调整大小 我已经尝试了下面的代码 但它不起作用 因为我认为没有 最大宽度 属性 table dataTable paging false info false searching false c
  • R 编程常用工具

    如果已经以不同的方式问过这个问题 我深表歉意 但我找不到任何达到我想要的东西 我真的是从其他软件包 SPSS 开始接触 R 的 当我了解真正可以做什么时 我意识到我还需要其他 工具 这让我想到了我的问题 您有哪些用于开发 R 代码的设置 我
  • 如何在 R 中绘制一列与其余列的关系图

    我有一个数据集 其中 1 是时间 接下来的 14 个是幅度 我想在一张图表上散布所有大小与时间的关系 其中每个不同的列都是网格化的 分层在另一个之上 我想使用原始数据来制作这些图表 并单独制作它们 但只想执行此过程一次 数据集A 唯一的自变
  • 读取R中打开的Excel文件

    有没有办法将打开的Excel文件读入R 当Excel中打开一个excel文件时 Excel会对文件加锁 比如R中的read方法无法访问该文件 你能绕过这个锁吗 Thanks 编辑 这发生在带有原始 Excel 的 Windows 下 发生错
  • 手动设置scale_fill_distiller()的比例

    我正在尝试制作一系列图表进行比较 举例来说 我想使用iris数据集来制作这样的图 其中我已过滤以仅查看 setosa 物种 library ggplot2 library dplyr iris gt filter Species setos
  • 如何使用 xpath 检查某个对象在网页中是否可见?

    我正在 R 中使用 RSelenium 包来进行网络抓取 有时加载网页后 需要检查某个对象在网页中是否可见 例如 library RSelenium open a browser RSelenium startServer remDr lt
  • 用表达式分割轴标签

    我有一个带有包含表达式的长标签的图 我想将其分成两行 在表达式中添加 n 结果不符合预期 ylabel lt expression A very long label with text and n expression alpha bet
  • ubuntu中R的igraph包的安装

    我使用以下命令在 ubuntu 中安装 R 的 igraph 包 install packages igraph 但我收到一条错误消息 警告 无法访问存储库的索引 http ftp iitm ac in cran src contrib h
  • 删除字符串末尾的句点和数字

    如何删除尾随句点 后面紧跟一个数字 长度为一位或两位数字 例子 z lt c awe p 56 red 45 ted 5 you 88 tom 我只想删除 45和 5 你只需要一个简单的正则表达式 z new gsub 0 9 z 一些评论
  • R 将多个值与向量进行比较并返回向量[重复]

    这个问题在这里已经有答案了 我有一个向量 A 对于 A 的每个元素 我想检查它是否等于第二个向量 Targets 中的任何元素 我想要一个逻辑值向量 其长度为 A 作为返回 也提到了同样的问题here http r 789695 n4 na
  • 如何在knitr和RStudio中为word和html设置不同的全局选项?

    我正在使用 RStudio 0 98 932 和 knitr 1 6 想要为word和html设置不同的全局knitr选项 例如 想要将word的fig width和fig height设置为6 html的fig width和fig hei
  • 获取函数的命名空间

    我正在开发一个包 我希望在其中向对象添加编辑历史记录 该包允许其他包注册用于编辑对象的函数 我正在寻找一种方法来记录注册用于编辑的函数的包的版本 问题是 给定一个函数 如何从导出的位置获取包 我的想法是调查它的搜索路径 但是search 仅
  • 使用字符串中的变量名称访问变量值,R

    Intro 一个数据集有大量的age year变量 age 1990 age 1991 etc 我有一个字符串值数组length age years 表示这些变量 使得age years 1 回报 age 1990 etc Need 我想搜
  • rpart“as.character(x) 中的错误:无法强制类型 'builtin' 为类型 'character' 的向量”消息是什么意思?

    我一直在用头撞rpart几天了 尝试为我拥有的这个数据集制作分类树 我认为现在是时候询问生命线了 我确信这是我没有看到的愚蠢的事情 但这里是我一直在做什么 EuropeWater lt read csv file paste Users a
  • R、Rcpp 与 Armadillo 中矩阵 rowSums() 与 colSums() 的效率

    背景 来自 R 编程 我正在扩展到 C C 形式的编译代码Rcpp 作为循环交换 以及一般的 C C 效果的实践练习 我实现了 R 的等效项rowSums and colSums 矩阵的函数Rcpp 我知道它们以 Rcpp 糖的形式存在 并
  • R中的字典数据结构

    在 R 中 我有 例如 gt foo lt list a 1 b 2 c 3 如果我输入foo I get a 1 1 b 1 2 c 1 3 我怎样才能看透foo仅获取 键 列表 在这种情况下 a b c R 列表可以具有命名元素 因此可
  • 为什么数据帧上的 is.vector 不返回 TRUE?

    tl dr R 中的向量到底是什么 长版 R 中很多东西都是向量 例如 数字是长度为 1 的数值向量 is vector 1 1 TRUE 列表也是一个向量 is vector list 1 1 TRUE 好的 所以列表是一个向量 显然 数
  • 需要在R中按行绑定列表数据

    我在 R 中按行绑定列表时遇到问题 我的列表数据集是 id 1 data k 1 id k b c 1 1 1 3 data k 2 id k b c 1 2 1 4 id 2 data k 1 id k b c 2 1 1 6 data
  • 如何在 Shiny 中提取动态生成的输入值?

    我正在创建一个闪亮的应用程序 它将根据客户的不同功能为客户生成分数 在我闪亮的应用程序中 我提供了 checkboxGroupInput 来选择所需的功能 根据所选功能 应用程序将动态地将 numericInput 添加到 Web ui 以

随机推荐