Передача заголовка в качестве аргумента в Rscript (результат отличается от запуска кода в графическом интерфейсе)

Я работаю над фрагментом кода, который, среди прочих переменных, передает заголовок из 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

Теперь я хочу изменить заголовок моих данных на заголовок, который я передал в качестве аргумента. Все следующие фрагменты кода работают по желанию, когда я запускаю их из графического интерфейса (в моем случае из 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.

У кого-нибудь есть объяснение/решение для этого? Любые идеи высоко ценятся.


person KJ_    schedule 24.02.2014    source источник
comment
Не могли бы вы напечатать, что представляет собой объект header? Я думаю, что лучше объединить столбцы с cbind, если они имеют одинаковую длину. (Строка (2) перезаписывает строку (1), поэтому вам не нужна первая строка)   -  person llrs    schedule 24.02.2014
comment
В вашем сценарии это правильно? Rscript script.R "c("column1","column2","column3") - вроде бы есть открывающая двойная кавычка без закрывающей. Это в скрипте или ошибка копирования/вставки?   -  person Josh Jolly    schedule 24.02.2014
comment
Джош Джолли, это действительно была ошибка копирования/вставки.   -  person KJ_    schedule 24.02.2014


Ответы (2)


Проблема в том, что если вы передаете аргумент в виде строки, вы должны преобразовать его в вектор, иначе это будет просто вектор длины 1. Для этого вам придется использовать eval и 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
person nograpes    schedule 24.02.2014
comment
Другой вариант - передать все имена столбцов в виде отдельных аргументов, чтобы избежать eval и parse. - person nograpes; 24.02.2014
comment
Правда, я думал об этом. Однако он менее общий (например, для разной длины заголовка) и, на мой взгляд, менее элегантный. - person KJ_; 25.02.2014

Я предполагаю, что, поскольку вектор является типом R, когда вы вводите его через сценарий bash, Unix не распознает его как таковой и передает его R в виде строки. Таким образом, R не знает, как обращаться с ним как с вектором имен столбцов (или вообще с вектором, если на то пошло), и поэтому не знает, как разбить его с помощью цикла for. О скольких именах столбцов мы говорим здесь? Если их действительно немного, я бы, вероятно, просто ввел их как отдельные аргументы командной строки и объединил их в список, если их много, я бы ввел их как длинный поток с четко определенным разделителем и использовал обработку текста для разбить их на список, аля:

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

Не имея возможности точно воспроизвести ваши данные и сценарий, я не могу дать вам более точный ответ, но, надеюсь, это поможет. Вот как я это делаю, когда мне нужно передать список в R через сценарии оболочки.

person TomR    schedule 24.02.2014