使用 R 4.1.3 我观察到:
var <- 0
> if(is.data.frame(var) || is.vector(var)) var <- as.matrix(var)
> is.null(var) || (!is.matrix(var) && var == 0) || (dim(var)==c(1,1) && var[1,1]==0)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)
但是,在 R 4.2.1 中,我观察到同一代码上的警告
> var <- 0
> if(is.data.frame(var) || is.vector(var)) var <- as.matrix(var)
> is.null(var) || (!is.matrix(var) && var == 0) || (dim(var)==c(1,1) && var[1,1]==0)
[1] TRUE
Warning message:
In dim(var) == c(1, 1) && var[1, 1] == 0 :
'length(x) = 2 > 1' in coercion to 'logical(1)'
Run Code Online (Sandbox Code Playgroud)
很难在这里找到根本原因。对于现在发生这种情况的原因以及好的解决方案有什么想法吗?
我正在努力在R 中复制绘图密度图示例。示例页面上使用的代码是
library(plotly)
dens <- with(diamonds, tapply(price, INDEX = cut, density))
df <- data.frame(
x = unlist(lapply(dens, "[[", "x")),
y = unlist(lapply(dens, "[[", "y")),
cut = rep(names(dens), each = length(dens[[1]]$x))
)
fig <- plot_ly(df, x = ~x, y = ~y, color = ~cut)
fig <- fig %>% add_lines()
fig
Run Code Online (Sandbox Code Playgroud)
当然,这工作得很好,并且可以快速预览数据
> str(df)
'data.frame': 2560 obs. of 3 variables:
$ x : num -1115 -1073 -1032 -991 -949 ...
$ y : num 6.74e-08 9.02e-08 1.20e-07 1.57e-07 2.06e-07 ...
$ …
Run Code Online (Sandbox Code Playgroud) 我有一个非常大的固定宽度文件,需要使用我的 Shiny 应用程序读取。我的程序目前的结构方式是 ui.R 包含一个 fileInput 允许用户使用浏览器定位文件。
在服务器端,我只捕获文件的路径,如下所示:
path2file <- reactive({
infile <- input$path2file
if (is.null(infile)) return(NULL)
infile$datapath
})
Run Code Online (Sandbox Code Playgroud)
随后的函数将该路径作为输入,并根据其布局规范继续读入文件。这一切都很好;然而,当处理非常大的 fwf 文件时,我的程序会大大减慢,并且需要数小时才能使用 fileInput 读取文件的路径名
我怀疑 fileInput 实际上正在读取整个文件,然后我的函数只返回数据路径,即使我没有在函数中明确读取任何文件格式类型。
我的目标是继续使用我现在已经构建的程序,并使用我的 fileInput 仅获取该文件的路径。我在 SO 上找到了这个主题,并认为这是一个可能的选择。
使用浏览按钮从 Shiny UI(不仅仅是目录)获取文件路径而不上传文件
但是,我的目标是最小化我拥有的包依赖项的数量;这已经成为一个大问题,所以如果我必须使用额外的包,我会,但我想不惜一切代价避免这种情况。
我尝试了这个便宜的技巧:
path2file <- reactive({
infile <- input$path2file
if (is.null(infile)) return(NULL)
scan(infile$datapath, n = 1)
infile$datapath
})
Run Code Online (Sandbox Code Playgroud)
认为这将是一个快速的解决方法,但它也非常慢,所以我怀疑它也不是只读取 n = 1。所以,我的问题是任何人都可以确定一种使用 fileInput 来允许用户定位文件的方法并让服务器端功能仅捕获路径而不读取文件或尝试以任何方式解析它?更重要的是,这是否可以单独使用 base R 和 Shiny 中的函数来完成,而不必从其他扩展包中获取函数?
以上是server.R文件中相关代码部分,ui.R文件中相关代码部分是
fileInput('path2dor', 'Choose the DOR .txt file to format',
accept=c('text/csv',
'text/comma-separated-values,text/plain', '.csv')),
Run Code Online (Sandbox Code Playgroud)
谢谢你的建议。
我有以下代码位于优化例程中。因此,虽然速度相当快,但分析显示产生结果的行被称为res
我的代码中最大的瓶颈。
我尝试了很多方法来改进这一点,并最终得到了最后一行:
res <- exp(X %*% log(pr.t) + mX %*% log(1 - pr.t)) %*% wts
Run Code Online (Sandbox Code Playgroud)
在我的问题中,矩阵的元素X
是固定的,并且不会随着迭代而改变。因此,我还可以计算、存储和回收X
和mX
。每次迭代发生的变化是我在对象中计算的一些概率pr.t
。
我尝试过 Rcpp,但 Rcpp 与我工作中的 R 代码一样快。
我现在向这个小组发出呼吁,看看是否有人能找到一种绝妙的方法来加快最终产品的生产线速度res
。下面是设置问题的示例代码,给出了实际问题的可重现示例。
X <- matrix(sample(c(0,1), 5000, replace = TRUE), 1000, 5)
mX <- 1 - X
pr.t <- matrix(runif(75), 5, 15)
wts <- runif(15)
res <- exp(X %*% log(pr.t) + mX %*% log(1 - pr.t)) %*% wts
Run Code Online (Sandbox Code Playgroud) 我发现 R 代码中最昂贵的部分是以下sapply
调用:
L <- 2000
score <- sample(1:3, L, replace = TRUE)
d <- c(0, -1, 0.5)
sapply(1:L, function(i) sum(d[1:score[i]]))
Run Code Online (Sandbox Code Playgroud)
d
该调用获取从索引 1 到索引 的向量的总和score[i]
,循环遍历变量中的每个元素score
。挑战在于该代码作为优化例程的一部分进行评估并运行很多很多次。
我正在尝试以矢量化方式执行相同的计算,但有点困难。我想我可以创建一个这样的矩阵:
d.mat <- matrix(rep(d, L), nrow = L, byrow = TRUE)
Run Code Online (Sandbox Code Playgroud)
然后以某种方式计算rowSums(d.mat)
从第 1 列到score[i]
row 中的列i
。有谁知道有一种方法可以在不循环的情况下做到这一点?sapply
我想,如果可能的话,考虑到rowSums
以下基准中的相对速度,这将比 快得多:
library(microbenchmark)
microbenchmark(sapply(1:L, function(i) sum(d[1:score[i]])),
rowSums(d.mat),
times = 100)
Run Code Online (Sandbox Code Playgroud)
或者也许有人看到了更好的第三种选择。