0

我正在编写一段代码,除其他变量外,它将标头从 bash 脚本传递给 R。这可能看起来很愚蠢或愚蠢,但对于我的特殊需求,这正是我想要的。所以,我有一个 bash 脚本:

#!/bin/bash
Rscript script.R "c("column1","column2","column3")"

我已经对其进行了简化,但要点在那里:它启动了一个 Rscript 实例,并将所需的标头作为参数传递。R 脚本包含以下部分或相关代码:

args<-commandArgs(TRUE) # enable arguments
header <- args[1] # store the first argument in a variable

现在,我想将数据的标头更改为作为参数传递的标头。当我从 GUI(在我的例子中是 Rstudio)运行它时,以下代码都可以按需要工作:

(1) colnames(data) <- header
(2) colnames(data) <- paste(header, sep=" ")
(3) for (i in 1:length(header)){colnames(data)[i] <- header[i]}

所有这些命令都将标题分成 3 部分,以便所有三列都有一个新标题(分别为“column1”、“column2”和“column3”)。但是,如果我像上面描述的那样从我的 bash 脚本运行它(调用 Rscript),它就不起作用。相反,它给出了以下输出:

 c(column1,column2,column3)                                      Chromosome
1                                                            rs10          7
2                                                       rs1000000         12
3                                                      rs10000010          4
4                                                      rs10000012          4
5                                                      rs10000013          4
6                                                      rs10000017          4
   Position 
1  92221824 
2 125456933 
3  21227772 
4   1347325 
5  36901464 
6  84997149 

...显然,这不是我想要的。上面列出的三个命令现在都不能正常工作。这让我感到困惑,因为无论我以何种方式运行它,无论是 Rstudio 还是 Rscript,我都希望我的代码的结果是相同的。

有人对此有解释/解决方案吗?任何想法都非常感谢。

4

2 回答 2

3

问题是,如果您将参数作为字符串传递,则必须将其解析为向量,否则它将只是长度为 1 的向量。为此,您必须使用evaland parse

这是一个例子script.R

args<-commandArgs(TRUE)
header<-eval(parse(text=args[1]))

data<-data.frame(one=1:10,two=1:10,three=1:10)
colnames(data)<-header
head(data)

以下是在 bash 中传递参数的方法:

Rscript script.R "c('col1','col2','col3')"

哪个会返回:

#   col1 col2 col3
# 1    1    1    1
# 2    2    2    2
# 3    3    3    3
# 4    4    4    4
# 5    5    5    5
# 6    6    6    6
于 2014-02-24T15:57:20.070 回答
0

我的猜测是,由于向量是 R 类型,当您通过 bash 脚本输入它时,Unix 无法识别它并将其作为字符串传递给 R。因此,R 不知道将其视为列名的向量(或者根本就不是向量),因此不知道如何通过 for 循环将其分解。我们在这里讨论了多少列名?如果它真的只有几个,我可能只是将它们作为单独的命令行参数输入并将它们组合成一个列表,如果它很多,那么我会将它们作为一个带有明确分隔符的长流输入并使用文本处理来将它们分成一个列表,阿拉:

myvector <- "col1,col2,col3,col4"
mycolnames <- unlist(as.list(strsplit(myvector,",")[[1]]))

由于无法准确地重现您的数据和脚本,我无法给您更准确的答案,但希望这会有所帮助。当我需要通过 shell 脚本将列表传递给 R 时,我就是这样做的。

于 2014-02-24T16:18:21.800 回答