小编JRR*_*JRR的帖子

向量上的复制修改语义不会附加到循环中.为什么?

这个问题听起来在这里得到了部分回答,但这对我来说还不够具体.当通过引用更新对象以及复制对象时,我想更好地理解.

更简单的例子是矢量增长.下面的代码在R中非常低效,因为在循环之前没有分配内存,并且在每次迭代时都进行了复制.

  x = runif(10)
  y = c() 

  for(i in 2:length(x))
    y = c(y, x[i] - x[i-1])
Run Code Online (Sandbox Code Playgroud)

分配内存使能保留一些内存,而无需在每次迭代时重新分配内存.因此,这个代码速度极快,特别是对于长向量.

  x = runif(10)
  y = numeric(length(x))

  for(i in 2:length(x))
    y[i] = x[i] - x[i-1]
Run Code Online (Sandbox Code Playgroud)

这是我的问题.实际上,当矢量更新时,它确实会移动.有一个副本,如下所示.

a = 1:10
pryr::tracemem(a)
[1] "<0xf34a268>"
a[1] <- 0L
tracemem[0xf34a268 -> 0x4ab0c3f8]:
a[3] <-0L
tracemem[0x4ab0c3f8 -> 0xf2b0a48]:  
Run Code Online (Sandbox Code Playgroud)

但在循环中,此副本不会发生

y = numeric(length(x))
for(i in 2:length(x))
{
   y[i] = x[i] - x[i-1]
   print(address(y))
}
Run Code Online (Sandbox Code Playgroud)

[1] "0xe849dc0"
[1] "0xe849dc0"
[1] "0xe849dc0"
[1] "0xe849dc0" …
Run Code Online (Sandbox Code Playgroud)

r pass-by-reference pass-by-value

9
推荐指数
2
解决办法
124
查看次数

分组是否在数据中并行化.表1.12.0?

在更改日志中,data.table v1.12.0我注意到以下内容:

子集,排序和分组现在使用更多并行性

我测试过我是否可以加快一些分组但没有任何成功.我做了几个不同的测试,我总是得到相同的结果.分组实际上是并行的吗?也许我没有正确使用线程选项?正如您所看到的那样data.table已经编译,openmp否则会setDTthread打印一条消息告诉用户没有支持openmp.这是我的一个测试的再现示例.

library(data.table)

n = 5e6
k = 1e4

DT = data.table(x = runif(n), y = runif(n), grp = sample(1:k, n, TRUE))

# Any function not too fast
f = function(x,y) as.list(eigen(cov(cbind(x,y)), only.values = TRUE)$value)

setDTthreads(1)
getDTthreads()
#> [1] 1

system.time(DT[ , f(x,y), by = grp])
#> utilisateur     système      écoulé 
#>       3.365       0.008       3.374

setDTthreads(0)
getDTthreads(T)
#> omp_get_max_threads() = 4
#> omp_get_thread_limit() = 2147483647
#> DTthreads = 0 …
Run Code Online (Sandbox Code Playgroud)

r openmp data.table

8
推荐指数
1
解决办法
477
查看次数

data.table不计算by中的NA组

这个问题在这里有部分答案,但问题太具体了,我无法将其应用于我自己的问题.

我想在使用时跳过NA组的潜在重量计算by.

library(data.table)

DT = data.table(X = sample(10), 
                Y = sample(10), 
                g1 = sample(letters[1:2], 10, TRUE),
                g2 = sample(letters[1:2], 10, TRUE))

set(DT, 1L, 3L, NA)
set(DT, 1L, 4L, NA)
set(DT, 6L, 3L, NA)
set(DT, 6L, 4L, NA)

DT[, mean(X*Y), by = .(g1,g2)]
Run Code Online (Sandbox Code Playgroud)

在这里,我们可以看到最多有5个组,包括该(NA, NA)组.考虑到(i)该组是无用的(ii)这些组可能非常大并且(iii)实际计算比mean(X*Y)我能以有效方式跳过该组更复杂?我的意思是,没有创建剩余表的副本.确实以下工作.

DT2 = data.table:::na.omit.data.table(DT, cols = c("g1", "g2"))
DT2[, mean(X*Y), by = .(g1,g2)]
Run Code Online (Sandbox Code Playgroud)

grouping group-by r na data.table

7
推荐指数
1
解决办法
132
查看次数

gcc-8 -Wstringop-truncation有什么好的做法?

海湾合作委员会8增加了-Wstringop-truncation警告.来自https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82944:

在GCC 8.0中通过r254630为bug 81117添加的-Wstringop-truncation警告专门用于突出显示strncpy函数的非预期用途,该函数截断源字符串中的终止NUL字符.请求中给出的此类滥用的示例如下:

char buf[2];

void test (const char* str)
{
  strncpy (buf, str, strlen (str));
}
Run Code Online (Sandbox Code Playgroud)

我用这段代码得到了同样的警告.

strncpy(this->name, name, 32);

warning: 'char* strncpy(char*, const char*, size_t)' specified bound 32 equals destination size [-Wstringop-truncation`]
Run Code Online (Sandbox Code Playgroud)

考虑到this->namechar name[32]name是一个char*具有长度可能比32更大我想复制namethis->name和截断它,如果它是大于32更大的应该size_t是31而不是32?我糊涂了.this->nameNUL终止并不是强制性的.

c++ gcc strncpy gcc8

7
推荐指数
3
解决办法
5572
查看次数

integer64 和 Rcpp 兼容性

在不久的将来,我的包中将需要 64 位整数。我正在研究基于该bit64包的可行性。data.table基本上,我计划在 S3类中包含一列或多列interger64,并计划使用 Rcpp 将此表传递给 C++ 函数。

以下来自Rcpp 图库的nanotime 示例清楚地解释了如何在 double 向量上构建 64 位 int 向量,并解释如何创建integer64从 C++ 到 R 的对象。

我现在想知道如何处理interger64从 R 到 C++ 的问题。我想我可以颠倒这个原则。

void useInt64(NumericVector v) 
{
    double len = v.size();
    std::vector<int64_t> n(len);

    // transfers values 'keeping bits' but changing type
    // using reinterpret_cast would get us a warning
    std::memcpy(&(n[0]), &(v[0]), len * sizeof(double));

    // use n in further computations
}
Run Code Online (Sandbox Code Playgroud)

那是对的吗?还有其他方法可以做到这一点吗?我们可以使用包装器吗as<std::vector<int64_t>>(v)?对于最后一个问题,我猜转换不是基于位到位的复制。

r rcpp data.table bit64

6
推荐指数
0
解决办法
362
查看次数

压缩 R 包中的共享库

我的包.so文件大于 3 MB(最多 10 MB),具体取决于编译器和系统。这会R CMD check在我的包中生成一个注释多年。我的包不包含这么多代码,所以我最终搜索以减小大小,我发现了 Dirk Eddelbuettel 的这篇优秀文章

按照我SHLIB_CXX11LDFLAGS = -Wl,-S -shared在我的.R/Makevars库中添加的建议,我的库大小从 10.4 MB 下降到 580 KB!我第一次有 0 个错误、0 个警告和 0 个注释。是的!

然而,这只是局部解决方案。在帖子的最后,建议以下内容src/Makevars

strippedLib: $(SHLIB)
        if test -e "/usr/bin/strip"; then /usr/bin/strip --strip-debug $(SHLIB); fi

.phony: strippedLib
Run Code Online (Sandbox Code Playgroud)

但有人提到:

而且这个方案甚至可能通过 CRAN 审核,但我还没有尝试过。

我的问题如下:

  • 该帖子来自 2017 年 8 月。有人知道它是否通过 CRAN 检查吗?
  • 这是一个 GNU/Linux(可能是 macOS)解决方案。有跨平台选项吗?

r rcpp r-package

6
推荐指数
1
解决办法
119
查看次数

在data.table中进行浅表复制

我在SO主题中读到了Matt Dowle的答案,该答案涉及在shallow中创建浅表副本的功能data.table。但是,我再也找不到该主题。

data.table没有名为的任何导出函数shallow。有一个内部文件,但没有记录。我可以安全使用吗?它的行为是什么?

我想做的是一个大表的内存有效副本。让我们DT做一个有n列的大表,并使用f一个函数有效地增加一个列。这样有可能吗?

DT2 = f(DT)
Run Code Online (Sandbox Code Playgroud)

DT2是,其中data.table包含n指向原始地址的列(无较深的副本),并且仅存在一个用于的地址DT2。如果是,我可以追加DT1什么DT2[, col3 := NULL]

r shallow-copy data.table

5
推荐指数
1
解决办法
862
查看次数

为什么空矩阵是 208 字节?

在他的书中,Hadley Wickam 解释了为什么空向量在memory部分中是 40 个字节。但是矩阵呢?矩阵的属性中也至少有两个整数来存储列数和行数。但这不足以解释为什么空矩阵是 208 字节。我期待像 48 字节这样的东西。

> object.size(matrix())
208 bytes
Run Code Online (Sandbox Code Playgroud)

r

5
推荐指数
0
解决办法
71
查看次数

R 3.5 软件包“lattice”由具有不同内部结构的 R 版本安装

我今天将 R 3.4.4 更新为 R 3.5.0。我的包裹不能再通过R CMD check了。它在 处失败checking whether package can be installed ... ERROR

另一方面,我的包可以工作,只要我不检查它,我就可以安装和使用它。

错误如下:

Error: package or namespace load failed for ‘sp’:
 package ‘lattice’ was installed by an R version with different internals; it needs to be reinstalled for use with this R version
Error : package ‘sp’ could not be loaded
Run Code Online (Sandbox Code Playgroud)

我尝试通过lattice以下方式重新安装:

sudo apt-get --reinstall install r-cran-lattice
Run Code Online (Sandbox Code Playgroud)

或者

remove.packages("lattice", lib="~/R/x86_64-pc-linux-gnu-library/3.5")
install.package("lattice")
Run Code Online (Sandbox Code Playgroud)

lattice在这两种情况下都正确安装了软件包。但这并不能解决我的问题。此外,我确保有一个lattice删除一个版本r-cran或自编译版本的单一版本。什么都行不通。

编辑顺便说一句,我可以做到 …

r lattice r-package

5
推荐指数
1
解决办法
5864
查看次数

R-devel 带有来自摇杆的消毒剂

我试图安装R与USBAN从devel的ASAN摇杆。按照自述文件我试过:

sudo docker run --rm -ti rocker/r-devel-san
Run Code Online (Sandbox Code Playgroud)

这花了很长时间下载,但最后没问题。然后我安装了sanitizers包来测试 R 是否存在已知错误。

install.package("sanitizers")
Run Code Online (Sandbox Code Playgroud)

我试图得到一个错误

> sanitizers::stackAddressSanitize(42)
[1] 24
> sanitizers::heapAddressSanitize(1)
[1] 0
Run Code Online (Sandbox Code Playgroud)

我没有收到任何错误,所以我猜我用 docker 运行的 R 版本不是用消毒剂支持构建的。或者我只是在某个地方错过了一些东西。这是我第一次使用 docker。

r rcpp docker address-sanitizer r-package

5
推荐指数
1
解决办法
92
查看次数

如何将激光雷达格式 las 转换为 data.frame?

激光雷达数据只是 3D 坐标,通常采用las文件格式。\xd0\xa1内容示例

\n
library(rgdal)\nlibrary(raster)\nlibrary(tmap)\nlibrary(tmaptools)\nlibrary(lidR)\nlibrary(RStoolbox)\nlas_cat <- readLAScatalog("C:/1/078-638.las")\nsummary(las_cat)\nopt_chunk_size(las_cat) <- 500\nplot(las_cat, chunk_pattern = TRUE)\nlas_cat\n#> class       : LAScatalog (v1.2 format 1)\n#> extent      : 637999, 638240.5, 6077999, 6079999 (xmin, xmax, ymin, ymax)\n#> coord. ref. : NA \n#> area        : 483081.1 units\xc2\xb2\n#> points      : 3.68 million points\n#> density     : 7.6 points/units\xc2\xb2\n#> density      : 5.6 pulses/units\xc2\xb2\n#> num. files  : 1\n
Run Code Online (Sandbox Code Playgroud)\n

有没有办法获得data.frameR 的典型点坐标?\n作为示例,我们可以使用来自此http://data.wvgis.wvu.edu/elevation/的数据。\n此外,有没有办法获得角度反射,data.frame激光雷达文件中的反射数量?

\n

r geospatial lidar las lidr

5
推荐指数
1
解决办法
1054
查看次数

来自Voronoi的Delaunay使用boost:缺少具有非整数点坐标的三角形

遵循这两个资源:

我写了一个Delaunay三角剖分boost.如果点坐标是积分的,它可以正常工作(我生成了几个随机测试,但没有观察到错误).但是,如果这些点是非整数的,我会发现许多不正确的三角剖分,边缘缺失或边缘错误.

例如,此图像已使用舍入值构建并且是正确的(请参阅下面的代码)

在此输入图像描述

但是这个图像是用原始值构建的并且不正确(参见下面的代码)

在此输入图像描述

此代码重现了这两个示例(没有显示).

#include <boost/polygon/voronoi.hpp>
using boost::polygon::voronoi_builder;
using boost::polygon::voronoi_diagram;

struct Point
{
  double a;
  double b;
  Point(double x, double y) : a(x), b(y) {}
};

namespace boost
{
  namespace polygon
  {
    template <>
    struct geometry_concept<Point>
    {
      typedef point_concept type;
    };

    template <>
    struct point_traits<Point>
    {
      typedef double coordinate_type;

      static inline coordinate_type get(const Point& point, orientation_2d orient)
      {
        return (orient == HORIZONTAL) ? point.a : point.b;
      }
    };
  }  // polygon
}  // boost

int …
Run Code Online (Sandbox Code Playgroud)

c++ boost voronoi delaunay boost-polygon

4
推荐指数
1
解决办法
706
查看次数

矢量与不同类型的向量

我想构建一个向量的向量.这个问题已经多次发布在SO上,但我找不到令人满意的答案.那是因为:

  • 每个向量可以有不同的类型
  • 我不知道编译时的类型
  • 我不知道它将包含多少向量

基本上我希望以后可以在伪代码中做类似的事情

types = ["char", "int", "double", "int"]
container<vector> x

foreach (type in types)
{
  if (type == "char")
    x.push_back(vector<char>)
  else if (type == "int")
    x.push_back(vector<int>)
  else
    x.push_back(vector<double>)
}
Run Code Online (Sandbox Code Playgroud)

然后我希望能够做到这一点

x[0].push_back("a")
x[1].push_back(1)
x[2].push_back(3.1416)
Run Code Online (Sandbox Code Playgroud)

我想boost::any可能会对我有所帮助,但我还不熟悉.

关键是,即使听起来很奇怪,这也是我想做的事情.我不想要一个结构向量,我真的想要一个包含std::vector不同类型的容器(无论哪一个).原因是因为我正在阅读二进制文件.文件的标题表示数据的数量及其类型,但它可以从文件更改为另一个文件.因此在编译时无法知道.

c++ boost stl vector c++11

3
推荐指数
1
解决办法
388
查看次数