我在轉換為整數的大向量中在 r 中創建/修改了資料。我需要將資料寫入二進制檔案,該檔案將由另一個應用程式 ImageJ 讀取。我找不到 R 函式來執行此操作,所以我嘗試了 Rcpp。寫入的檔案大小符合預期,但個別資料不是。我的測驗示例如下。
RStudio 2021.09.0 構建 351
R 版本 4.1.3 (2022-03-10) -- “一個俯臥撐”
MacOS 蒙特雷 12.4 版
Rcpp 函式
r <- 1:20
typeof(r)
[1] "integer"
#include <Rcpp.h>
#include <stdlib.h>
#include <string>
#include <stdio.h>
using namespace Rcpp;
// [[Rcpp::export]]
int cpp_saveAsBin (const IntegerVector & imgData, const std::string fname) {
FILE *outP = fopen(fname.c_str(), "wb");
if (outP == NULL) Rcpp::stop("Cannot open file", fname);
int res = fwrite(imgData, sizeof(int), imgData.size(), outP);
fclose(outP);
return (res);
}
測驗
> r <- 1:20
> typeof(r)
[1] "integer"
> cpp_saveAsBin(as.integer(r), "test.rawP")
[1] 20
用 xxd 檢查(修剪以縮短行。
xxd test.rawP
00000000: 8d00 0001 ffff 0000 e072 8259 0100 0000
00000010: 78a9 7058 0100 0000 0885 115b 0100 0000
00000020: 3880 c05f 0100 0000 0831 4b3c 0100 0000
00000030: c000 6f02 0060 0000 0200 0000 0100 0000
00000040: e072 8259 0100 0000 b04f 3938 0100 0000
這些值不是從 1 到 20 的二進制表示。這是怎么回事?有沒有更好的方法?
TIA
uj5u.com熱心網友回復:
你很親密。回想一下,fwrite()
函式的第一個引數是void*
要寫入的給定型別和大小的記憶體塊。
SEXP
但是您指出了最小元資料和實際 20 個整數的(內部是 a )R 容器物件的開頭,而不是 20 個整數!因此,通過制作它imgData.begin()
(或者同樣是 a &(imgData[0])
),您實際上撰寫了您想要撰寫的有效負載!
另一件好事是我們實際上可以通過 R 本身測驗讀回readBin
(如果你愿意,你也可以從 R 寫...)
我修改后的代碼版本以及測驗代碼如下。我還簡化了標題(為Rcpp.h
我們提供了我們需要的東西)并在 R 端不需要的演員表中洗掉):
代碼
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
int cpp_saveAsBin (const IntegerVector & imgData, const std::string fname) {
FILE *outP = fopen(fname.c_str(), "wb");
if (outP == NULL) Rcpp::stop("Cannot open file", fname);
int res = fwrite(imgData.begin(), sizeof(int), imgData.size(), outP);
fclose(outP);
return (res);
}
/*** R
r <- 1:20
typeof(r)
class(r)
cpp_saveAsBin(r, "/tmp/test.raw.bin")
fp <- file("/tmp/test.raw.bin", "rb")
readBin(fp, integer(), 20)
close(fp)
*/
輸出
> Rcpp::sourceCpp("~/git/stackoverflow/72610544/answer.cpp")
> r <- 1:20
> typeof(r)
[1] "integer"
> class(r)
[1] "integer"
> cpp_saveAsBin(r, "/tmp/test.raw.bin")
[1] 20
> fp <- file("/tmp/test.raw.bin", "rb")
> readBin(fp, integer(), 20)
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
> close(fp)
>
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/491972.html