data.table 与 dplyr:一个可以做得很好而另一个不能做或做得很差吗?

2023-12-05

Overview

我比较熟悉data.table,没有那么多dplyr。我读过一些dplyr小插图以及 SO 上出现的例子,到目前为止我的结论是:

  1. data.table and dplyr速度相当,除非有很多(即 >10-100K)组,以及在其他一些情况下(参见下面的基准)
  2. dplyr具有更易于访问的语法
  3. dplyr抽象(或将)潜在的数据库交互
  4. 有一些细微的功能差异(请参阅下面的“示例/用法”)

2.在我心目中并没有多大分量,因为我相当熟悉data.table,尽管我知道对于这两者的新用户来说这将是一个重要因素。我想避免争论哪个更直观,因为这与我从已经熟悉的人的角度提出的具体问题无关data.table。我还想避免讨论“更直观”如何导致更快的分析(当然是正确的,但同样,这不是我在这里最感兴趣的)。

Question

我想知道的是:

  1. 对于熟悉这些包的人来说,是否存在使用一个或另一个包更容易编码的分析任务(即所需的击键与所需的深奥程度的某种组合,其中每种击键较少是一件好事)。
  2. 与另一个包相比,在一个包中执行分析任务的效率是否显着提高(即超过 2 倍)。

One 最近的问题让我更多地思考这个问题,因为直到那时我才想到dplyr会提供超出我已经可以做的事情data.table。这里是dplyr解决方案(Q末尾的数据):

dat %.%
  group_by(name, job) %.%
  filter(job != "Boss" | year == min(year)) %.%
  mutate(cumu_job2 = cumsum(job2))

这比我的黑客尝试要好得多data.table解决方案。就是说,好data.table解决方案也相当不错(感谢 Jean-Robert、Arun,并注意这里我更喜欢单一语句而不是严格的最佳解决方案):

setDT(dat)[,
  .SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)], 
  by=list(id, job)
]

后者的语法可能看起来非常深奥,但如果您习惯的话,它实际上非常简单data.table(即不使用一些更深奥的技巧)。

理想情况下,我希望看到一些很好的例子dplyr or data.table方式更加简洁或者性能更好。

Examples

Usage

  • dplyr不允许返回任意行数的分组操作(来自艾迪的问题,注意:这看起来将在dplyr 0.5另外,@beginneR 展示了一种潜在的解决方法,使用do在对@eddi问题的回答中)。
  • data.table支持滚动连接(感谢@dholstius)以及重叠连接
  • data.table内部优化形式的表达式DT[col == value] or DT[col %in% values] for speed通过自动索引它使用二分查找同时使用相同的基本 R 语法。See here了解更多细节和一个小基准。
  • dplyr提供函数的标准评估版本(例如regroup, summarize_each_)可以简化编程使用dplyr(注意编程使用data.table绝对是可能的,只需要一些仔细的思考、替换/引用等,至少据我所知)

基准测试

  • I ran 我自己的基准并发现这两个包在“拆分应用组合”风格分析中具有可比性,除非存在大量组(> 100K)data.table变得更快。
  • @Arun跑了一些连接基准,表明data.table规模比dplyr随着组数量的增加(使用软件包和 R 最新版本中的最新增强功能进行更新)。另外,尝试获取时的基准独特的价值观 has data.table快约 6 倍。
  • (未经验证)有data.table较大版本的组/应用/排序速度提高 75%dplyr较小的速度快 40% (评论中的另一个问题,谢谢达纳斯)。
  • 马特,主要作者data.table, has 基准分组操作data.table, dplyr和蟒蛇pandas最多 20 亿行(RAM 中约 100GB).
  • An 80K 组的旧基准 has data.table快约 8 倍

Data

这是我在问题部分展示的第一个例子。

dat <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L), name = c("Jane", "Jane", "Jane", "Jane", 
"Jane", "Jane", "Jane", "Jane", "Bob", "Bob", "Bob", "Bob", "Bob", 
"Bob", "Bob", "Bob"), year = c(1980L, 1981L, 1982L, 1983L, 1984L, 
1985L, 1986L, 1987L, 1985L, 1986L, 1987L, 1988L, 1989L, 1990L, 
1991L, 1992L), job = c("Manager", "Manager", "Manager", "Manager", 
"Manager", "Manager", "Boss", "Boss", "Manager", "Manager", "Manager", 
"Boss", "Boss", "Boss", "Boss", "Boss"), job2 = c(1L, 1L, 1L, 
1L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L)), .Names = c("id", 
"name", "year", "job", "job2"), class = "data.frame", row.names = c(NA, 
-16L))

Answer recommended by R Language Collective

我们至少需要涵盖以下几个方面,以提供全面的答案/比较(排名不分先后):Speed, Memory usage, Syntax and Features.

我的目的是从 data.table 的角度尽可能清楚地涵盖其中的每一个。

注意:除非另有明确说明,否则当提及 dplyr 时,我们指的是 dplyr 的 data.frame 接口,其内部结构是使用 Rcpp 的 C++ 语言。


data.table 语法在形式上是一致的 -DT[i, j, by]。为了保留i, j and by在一起是设计使然。通过将相关操作放在一起,它允许轻松优化操作为speed更重要的是内存使用情况,并且还提供一些强大的功能,同时保持语法的一致性。

1. Speed

相当多的基准(尽管主要是关于分组操作)已添加到已经显示 data.table gets 的问题中faster比 dplyr 随着分组数和/或行数的增加而增加,包括马特的基准分组时从1000 万到 20 亿行(100GB 内存)100 - 1000 万组和不同的分组列,这也比较pandas。也可以看看更新的基准, 其中包括Spark and Polars以及。

在基准测试中,最好也涵盖这些剩余的方面:

  • 涉及的分组操作行的子集- IE。,DT[x > val, sum(y), by = z]类型操作。

  • 对其他操作进行基准测试,例如update and joins.

  • 还标杆内存占用除了运行时间之外的每个操作。

2. 内存使用情况

  1. 涉及的操作filter() or slice()dplyr 中的内存效率可能较低(在 data.frames 和 data.tables 上)。看这个帖子.

    注意哈德利的评论谈论speed(dplyr 对他来说很快就足够了),而这里主要关心的是memory.

  2. data.table 接口目前允许修改/更新列引用(请注意,我们不需要将结果重新分配回变量)。

     # sub-assign by reference, updates 'y' in-place
     DT[x >= 1L, y := NA]
    

    但dplyr永不通过参考更新。 dplyr 等效项为(请注意,结果需要重新分配):

     # copies the entire 'y' column
     ans <- DF %>% mutate(y = replace(y, which(x >= 1L), NA))
    

    对此的一个担忧是参考透明度。通过引用更新 data.table 对象,尤其是在函数内,可能并不总是可取的。但这是一个非常有用的功能:请参阅this and this有趣案例的帖子。我们想保留它。

    因此我们正在努力出口shallow()data.table 中的函数将为用户提供两种可能性。例如,如果不希望修改函数内的输入 data.table,则可以执行以下操作:

     foo <- function(DT) {
         DT = shallow(DT)          ## shallow copy DT
         DT[, newcol := 1L]        ## does not affect the original DT 
         DT[x > 2L, newcol := 2L]  ## no need to copy (internally), as this column exists only in shallow copied DT
         DT[x > 2L, x := 3L]       ## have to copy (like base R / dplyr does always); otherwise original DT will 
                                   ## also get modified.
     }
    

    通过不使用shallow(),保留旧功能:

     bar <- function(DT) {
         DT[, newcol := 1L]        ## old behaviour, original DT gets updated by reference
         DT[x > 2L, x := 3L]       ## old behaviour, update column x in original DT.
     }
    

    通过创建一个浅拷贝 using shallow(),我们知道您不想修改原始对象。我们在内部处理所有事情,以确保同时确保复制您修改的列仅当绝对必要时。实施后,这应该解决参考透明度完全解决问题,同时为用户提供两种可能性。

    还有,有一次shallow()导出dplyr的data.table接口应该避免几乎所有的副本。因此,那些喜欢 dplyr 语法的人可以将其与 data.tables 一起使用。

    但它仍然缺乏 data.table 提供的许多功能,包括通过引用进行(子)分配。

  3. 加入时聚合:

    假设您有两个 data.table,如下所示:

     DT1 = data.table(x=c(1,1,1,1,2,2,2,2), y=c("a", "a", "b", "b"), z=1:8, key=c("x", "y"))
     #    x y z
     # 1: 1 a 1
     # 2: 1 a 2
     # 3: 1 b 3
     # 4: 1 b 4
     # 5: 2 a 5
     # 6: 2 a 6
     # 7: 2 b 7
     # 8: 2 b 8
     DT2 = data.table(x=1:2, y=c("a", "b"), mul=4:3, key=c("x", "y"))
     #    x y mul
     # 1: 1 a   4
     # 2: 2 b   3
    

    并且你想得到sum(z) * mul对于每一行DT2按列连接时x,y。我们可以:

      1. 总计的DT1 to get sum(z), 2) 执行连接和 3) 乘法(或)

        数据表方式

        DT1[, .(z = sum(z)), keyby = .(x,y)][DT2][, z := z*mul][]
        

        dplyr 等效值

        DF1 %>% group_by(x, y) %>% summarise(z = sum(z)) %>% 
           right_join(DF2) %>% mutate(z = z * mul)
        
      1. 一次性完成这一切(使用by = .EACHI特征):

        DT1[DT2, list(z=sum(z) * mul), by = .EACHI]
        

    优点是什么?

    • 我们不必为中间结果分配内存。

    • 我们不必进行两次分组/散列(一次用于聚合,另一次用于连接)。

    • 更重要的是,我们想要执行的操作通过查看就很清楚了j in (2).

    Check 这个帖子详细解释by = .EACHI。没有中间结果被实现,并且连接+聚合是一次性执行的。

    看一下this, this and this真实使用场景的帖子。

    In dplyr你必须连接并聚合或先聚合然后连接,就内存而言(反过来又转化为速度),这两种方法都不那么高效。

  4. 更新并加入:

    考虑下面所示的 data.table 代码:

     DT1[DT2, col := i.mul]
    

    添加/更新DT1的专栏col with mul from DT2在那些行上DT2的键列匹配DT1。我认为没有与此操作完全相同的操作dplyr,即,无需避免*_join操作,这将不得不复制整个DT1只是向其中添加一个新列,这是不必要的。

    Check 这个帖子真实的使用场景。

总而言之,重要的是要认识到每一点优化都很重要。作为格蕾丝·霍珀会说,注意你的纳秒!

3. 语法

现在让我们看看syntax。哈德利评论here:

数据表非常快,但我认为它们的简洁使其成为可能更难学 and 使用它的代码在编写后更难阅读 ...

我觉得这句话毫无意义,因为它非常主观。我们或许可以尝试的是对比语法的一致性。我们将并排比较 data.table 和 dplyr 语法。

我们将使用如下所示的虚拟数据:

DT = data.table(x=1:10, y=11:20, z=rep(1:2, each=5))
DF = as.data.frame(DT)
  1. 基本聚合/更新操作。

     # case (a)
     DT[, sum(y), by = z]                       ## data.table syntax
     DF %>% group_by(z) %>% summarise(sum(y)) ## dplyr syntax
     DT[, y := cumsum(y), by = z]
     ans <- DF %>% group_by(z) %>% mutate(y = cumsum(y))
    
     # case (b)
     DT[x > 2, sum(y), by = z]
     DF %>% filter(x>2) %>% group_by(z) %>% summarise(sum(y))
     DT[x > 2, y := cumsum(y), by = z]
     ans <- DF %>% group_by(z) %>% mutate(y = replace(y, which(x > 2), cumsum(y)))
    
     # case (c)
     DT[, if(any(x > 5L)) y[1L]-y[2L] else y[2L], by = z]
     DF %>% group_by(z) %>% summarise(if (any(x > 5L)) y[1L] - y[2L] else y[2L])
     DT[, if(any(x > 5L)) y[1L] - y[2L], by = z]
     DF %>% group_by(z) %>% filter(any(x > 5L)) %>% summarise(y[1L] - y[2L])
    
    • data.table 语法很紧凑,而 dplyr 则相当冗长。情况(a)中的情况或多或少是等价的。

    • 在情况 (b) 中,我们必须使用filter()在 dplyr 中同时总结。但同时updating,我们必须移动里面的逻辑mutate()。然而,在 data.table 中,我们使用相同的逻辑来表达这两种操作 - 对其中的行进行操作x > 2,但在第一种情况下,得到sum(y),而在第二种情况下更新这些行y及其累计总和。

      这就是我们说的意思DT[i, j, by] form 是一致的.

    • 与情况 (c) 类似,当我们有if-else条件,我们能够表达逻辑"as-is"在 data.table 和 dplyr 中。但是,如果我们只想返回那些行if条件满足并跳过,否则我们不能使用summarise()直接(AFAICT)。我们必须filter()首先然后总结因为summarise()总是期待一个单值.

      虽然它返回相同的结果,但使用filter()这里使得实际操作不太明显。

      很可能使用filter()在第一种情况下也是如此(对我来说似乎并不明显),但我的观点是我们不必这样做。

  2. 多列聚合/更新

     # case (a)
     DT[, lapply(.SD, sum), by = z]                     ## data.table syntax
     DF %>% group_by(z) %>% summarise_each(funs(sum)) ## dplyr syntax
     DT[, (cols) := lapply(.SD, sum), by = z]
     ans <- DF %>% group_by(z) %>% mutate_each(funs(sum))
    
     # case (b)
     DT[, c(lapply(.SD, sum), lapply(.SD, mean)), by = z]
     DF %>% group_by(z) %>% summarise_each(funs(sum, mean))
    
     # case (c)
     DT[, c(.N, lapply(.SD, sum)), by = z]     
     DF %>% group_by(z) %>% summarise_each(funs(n(), mean))
    
    • 在情况 (a) 中,代码或多或少是等效的。 data.table 使用熟悉的基本函数lapply(), 然而dplyr介绍*_each()以及一堆功能funs().

    • 数据表的:=需要提供列名,而 dplyr 会自动生成。

    • 在情况 (b) 中,dplyr 的语法相对简单。改进多个函数的聚合/更新在 data.table 的列表中。

    • 但在情况 (c) 中,dplyr 将返回n()与列数一样多的次数,而不是仅仅一次。在data.table中,我们需要做的就是返回一个列表j。列表中的每个元素都将成为结果中的一列。所以,我们可以再次使用熟悉的基函数c()连接.N to a list它返回一个list.

    注意:再次,在 data.table 中,我们需要做的就是返回一个列表j。列表中的每个元素将成为结果中的一列。您可以使用c(), as.list(), lapply(), list()等等...基本函数来完成此任务,而无需学习任何新函数。

    您只需要学习特殊变量 -.N and .SD至少。 dplyr 中的等价物是n() and .

  3. Joins

    dplyr 为每种类型的连接提供单独的函数,而 data.table 允许使用相同语法的连接DT[i, j, by](并且有理由)。它还提供了等效的merge.data.table()作为替代功能。

     setkey(DT1, x, y)
    
     # 1. normal join
     DT1[DT2]            ## data.table syntax
     left_join(DT2, DT1) ## dplyr syntax
    
     # 2. select columns while join    
     DT1[DT2, .(z, i.mul)]
     left_join(select(DT2, x, y, mul), select(DT1, x, y, z))
    
     # 3. aggregate while join
     DT1[DT2, .(sum(z) * i.mul), by = .EACHI]
     DF1 %>% group_by(x, y) %>% summarise(z = sum(z)) %>% 
         inner_join(DF2) %>% mutate(z = z*mul) %>% select(-mul)
    
     # 4. update while join
     DT1[DT2, z := cumsum(z) * i.mul, by = .EACHI]
     ??
    
     # 5. rolling join
     DT1[DT2, roll = -Inf]
     ??
    
     # 6. other arguments to control output
     DT1[DT2, mult = "first"]
     ??
    
  • 有些人可能会为每个连接找到一个更好的单独函数(左、右、内部、反、半等),而其他人可能喜欢 data.table 的DT[i, j, by], or merge()与基础 R 类似。

  • 然而 dplyr joins 就是这么做的。而已。一点也没有少。

  • data.tables 可以在加入 (2) 时选择列,在 dplyr 中您需要select()首先在两个 data.frames 上加入,如上所示。否则,您将与不必要的列进行连接,然后稍后将其删除,这是低效的。

  • data.tables 可以在连接 (3) 时聚合,也可以在连接 (4) 时更新,使用 by = .EACHI 功能。为什么要对整个连接结果进行具体化以添加/更新几列?

  • data.table 能够滚动连接(5) - 滚动向前,LOCF, 向后滚动,NOCB, nearest.

  • data.table也有mult =选择的参数first, last or all匹配 (6)。

  • 数据表有allow.cartesian = TRUE防止意外无效连接的参数。

再次,语法与DT[i, j, by]带有允许进一步控制输出的附加参数。

  1. do()...

    dplyr 的 summarise 是专门为返回单个值的函数设计的。如果您的函数返回多个/不相等的值,您将不得不求助于do()。您必须事先了解所有函数的返回值。

     DT[, list(x[1], y[1]), by = z]                 ## data.table syntax
     DF %>% group_by(z) %>% summarise(x[1], y[1]) ## dplyr syntax
     DT[, list(x[1:2], y[1]), by = z]
     DF %>% group_by(z) %>% do(data.frame(.$x[1:2], .$y[1]))
    
     DT[, quantile(x, 0.25), by = z]
     DF %>% group_by(z) %>% summarise(quantile(x, 0.25))
     DT[, quantile(x, c(0.25, 0.75)), by = z]
     DF %>% group_by(z) %>% do(data.frame(quantile(.$x, c(0.25, 0.75))))
    
     DT[, as.list(summary(x)), by = z]
     DF %>% group_by(z) %>% do(data.frame(as.list(summary(.$x))))
    
  • .SD的等价物是.

  • 在 data.table 中,您可以放入几乎任何内容j- 唯一要记住的是它返回一个列表,以便列表中的每个元素都转换为一列。

  • 在 dplyr 中,不能这样做。不得不求助于do()取决于您对函数是否始终返回单个值的确定程度。而且速度相当慢。

再次,data.table 的语法与DT[i, j, by]。我们可以继续添加表达式j无需担心这些事情。

看一下这个问题 and this one。我想知道是否可以使用 dplyr 的语法直接表达答案......

总结一下,我特别强调了severaldplyr 的语法效率低下、有限或无法使操作简单明了的实例。这尤其是因为 data.table 对于“难以阅读/学习”的语法(如上面粘贴/链接的语法)引起了相当多的强烈反对。大多数涉及 dplyr 的帖子都讨论最简单的操作。那太好了。但认识到它的语法和功能限制也很重要,而且我还没有看到关于它的帖子。

data.table 也有其怪癖(我已经指出我们正在尝试修复其中一些怪癖)。正如我所强调的,我们还尝试改进 data.table 的连接here.

但人们还应该考虑 dplyr 与 data.table 相比缺乏的功能数量。

4. 特点

我已经指出了大部分功能here以及这篇文章中。此外:

  • fread- 快速文件阅读器已经面世很长时间了。

  • fwrite - a 并行化快速文件编写器现已推出。看这个帖子有关实施的详细说明和#1664以跟踪进一步的发展。

  • 自动索引- 另一个方便的功能,可以在内部按原样优化基本 R 语法。

  • 临时分组: dplyr通过对变量进行分组来自动对结果进行排序summarise(),这可能并不总是理想的。

  • 上面提到的 data.table 连接的许多优点(速度/内存效率和语法)。

  • 非等值连接:允许使用其他运算符进行连接<=, <, >, >=以及 data.table 连接的所有其他优点。

  • 重叠范围连接最近在 data.table 中实现了。查看这个帖子以获得基准概述。

  • setorder()data.table 中的函数允许通过引用对 data.tables 进行真正快速的重新排序。

  • dplyr 提供数据库接口使用相同的语法,但 data.table 目前没有。

  • data.table提供更快的等价物集合运算(扬·戈雷茨基撰写)-fsetdiff, fintersect, funion and fsetequal加上额外的all参数(如 SQL 中)。

  • data.table 加载干净,没有屏蔽警告,并且有一个描述的机制here for [.data.frame传递到任何 R 包时的兼容性。 dplyr 更改基本功能filter, lag and [这可能会导致问题;例如here and here.


Finally:

  • 在数据库上 - data.table 没有理由不能提供类似的接口,但这不是现在的优先事项。如果用户非常喜欢这个功能,它可能会被提高……不确定。

  • 关于并行性——一切都很困难,直到有人继续去做。当然,这需要付出努力(线程安全)。

    • 目前正在取得进展(在 v1.9.7 开发中),使用并行化已知耗时的部分来提高性能OpenMP.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

data.table 与 dplyr:一个可以做得很好而另一个不能做或做得很差吗? 的相关文章

  • par(mfrow=c(1,2)) 不显示并排密度图[重复]

    这个问题在这里已经有答案了 par mfrow c 1 2 plot 1 12 log y plot 1 2 xaxs i 然而 当我尝试做并排密度图时 图会单独输出 load the stud recs dataset library U
  • 替换列表列表中的元素

    The applyR 中的函数是简化 for 循环以获得输出的好方法 是否有一个等效的函数可以帮助人们在替换向量的值时避免 for 循环 通过示例可以更好地理解这一点 Take this list for example x list li
  • 从 R 中的向量中选择所有可能的元组

    我正在尝试用 R 编写一个程序 当给定一个向量时 将返回所有可能的tuples http en wikipedia org wiki Tuples该向量中的元素 例如 元组 c a b c c a b c 出租车 c a c c b c c
  • 将命名参数列表传递给函数?

    我想编写一个小函数来从适当的分布生成样本 例如 makeSample lt function n dist params values lt makeSample 100 unif list min 0 max 10 values lt m
  • 计算例如具有多列 data.frames 的列表中的平均值

    我有几个 data frames 的列表 每个 data frame 有几列 通过使用mean mylist first dataframe a我可以得到这个 data frame 中 a 的平均值 但是我不知道如何计算列表中存储的所有 d
  • numpy.histogram 的 hist 维度,密度 = True

    假设我有这个数组 A array 0 0019879 0 00172861 0 00527226 0 00639585 0 00242005 0 00717373 0 00371651 0 00164218 0 00034572 0 008
  • 如何从 R 运行带有特定模块的 perl 脚本?

    我可以从终端运行 perl 脚本 myperlscript pl 没有任何问题 但是 如果我尝试从 RStudio 中运行相同的 perl 脚本 则会出现以下错误 command lt myperlscript pl outputfile
  • 在shiny中过滤传单地图数据

    我在用传单地图设置这个闪亮的东西时遇到了麻烦 我的原帖 https stackoverflow com questions 50111566 applying leaflet map bounds to filter data within
  • 如何删除箱线图上的刻度线

    我试图从箱线图中删除 x 轴刻度线 但保留与刻度线关联的标签 这在基础 R 中可能吗 colors lt c lightskyblue3 gray78 gold1 wheat1 boxplot avgscore module data mi
  • 使用 purrr 迭代替换数据帧列中的字符串

    我想用purrr使用以下命令在数据框列上迭代运行多个字符串替换gsub 功能 这是示例数据框 df lt data frame Year 2019 Text c rep a aa 5 rep a bb 3 rep a cc 2 gt df
  • 如何计算R中移动窗口内的平均斜率

    我的数据集包含2个变量y 和 t 05s y 每 05 秒测量一次 我正在尝试计算移动中的平均坡度20秒窗口 即计算第一个 20 秒斜率值后 窗口向前移动一个时间单位 05 秒 并计算下一个 20 秒窗口 在以下位置生成连续 20 秒斜率值
  • 使用 pracma::findpeaks 识别持续峰值

    我的语法有问题peakpat内的选项findpeaks内的函数pramcaR 包 v 2 1 1 我使用的是 R 3 4 3 x64 Windows 我希望该函数能够识别可能有两个重复值的峰值 并且我相信该选项peakpat这就是我能做到的
  • 通过间接引用列来修改数据框中的某些值

    我正在整理一些数据 我们将失败的数据分类到垃圾箱中 并按批次计算每个分类箱的有限产量 我有一个描述排序箱的元表 这些行按升序测试顺序排列 一些排序标签带有非语法名称 sort tbl lt tibble tribble weight lab
  • 删除特定数据表上的所有边框

    我需要使用 PrimeFaces 隐藏一个数据表的所有边框 而不是全部 我尝试了很多事情 但没有人奏效 有谁知道该怎么做 我已将以下样式 单独 应用于ui datatable class border hidden important bo
  • 从命令行运行 R 代码 (Windows)

    我在名为 analysis r 的文件中有一些 R 代码 我希望能够从命令行 CMD 运行该文件中的代码 而无需通过 R 终端 并且我还希望能够传递参数并在我的代码中使用这些参数 例如就像下面的伪代码 C gt execute r scri
  • R独特的列或行与NA无可比拟

    有谁知道如果incomparables的论证unique or duplicated 曾经被实施过incomparables FALSE 也许我不明白它应该如何工作 无论如何 我正在寻找一个巧妙的解决方案 以仅保留与另一列相同的唯一列 或行
  • 将每列的值乘以 R 中另一个 data.frame 中的权重

    我有两个data frames df and weights 代码如下 df看起来像这样 id a b d EE f 1 this 0 23421153 0 02324956 0 5457353 0 73068586 0 5642554 2
  • 将数据框中重叠的范围合并到唯一的组中

    我有一个 n 行 3 的数据框 df lt data frame start c 178 400 983 1932 33653 end c 5025 5025 5535 6918 38197 group c 1 1 2 2 3 df sta
  • 将阴影区域添加到五分位数之间的直方图中

    All 我有一个包含 2 个直方图的图表 其中我还绘制了代表第 20 40 60 和 80 个百分位数的线条 下面的代码使用虚拟数据重现了类似的图表 data lt rbind data frame x rnorm 1000 0 1 g o
  • 相当于 min() 的 rowMeans()

    我在 R 邮件列表上多次看到这个问题 但仍然找不到满意的答案 假设我有一个矩阵m m lt matrix rnorm 10000000 ncol 10 我可以通过以下方式获得每行的平均值 system time rowMeans m use

随机推荐