Применить функцию к каждому столбцу базы данных - PullRequest
1 голос
/ 11 октября 2019

Я использую особую нишевую функцию, которая требует, чтобы имя переменной анализируемого столбца записывалось как имя объекта. Я хочу зациклить эту функцию на нескольких столбцах, но я не знаю, как преобразовать имя столбца в имя объекта для работы функции.

Вот пример:

library(caper)
library(ape)

tree = rtree(100)
data = data.frame(taxa = tree$tip.label, 
                  value1 = sample(c(0,1), 100, replace = TRUE),
                  value2 = sample(c(0,1), 100, replace = TRUE))

for(i in 2:3){
  phylo.d(data = data, phy = tree, 
          names.col = taxa,
          binvar = eval(substitute(colnames(data)[i]))
          )  
}

У меня проблема с аргументом binvar. Код, который у меня сейчас есть, не работает, но это была моя лучшая догадка. Это должно вернуть ошибку:

Error in phylo.d(data = data, phy = tree, names.col = taxa, binvar = eval(substitute(colnames(data)[i]))) : 'eval(substitute(colnames(data)[i]))' is not a variable in data.

Из приведенного выше аргумента names.col видно, как функция ожидает ввода имен столбцов (например, имени объекта). Затем функция использует deparse(substitute(binvar)) для извлечения столбца из кадра данных.

Кто-нибудь может предложить решение? (кроме переписывания функции).

1 Ответ

1 голос
/ 11 октября 2019

Мой подход заключается в построении строки для вызова функции ВЕСЬ перед передачей на evaluate. В этом случае итерации вашего цикла будут производить:

str="phylo.d(data=data,phy=tree,names.col=taxa,binvar=value1)"
str="phylo.d(data=data,phy=tree,names.col=taxa,binvar=value2)"

, а затем использовать print(eval(str2expression(str))) для оценки каждого. Я использовал print, потому что phylo.d, по-видимому, создает невидимый вывод.

Если вы хотите сохранить вывод вызова в phylo.d, затем создайте присвоение в приведенной выше строке и удалите оператор print.

Если вы чувствуете себя комфортно с пакетом rlang и квази-цитатой, вы, вероятно, можете создать более аккуратное решение.

Вот мое полное решение:

build.expr=function(i) {
   paste("phylo.d(data=data,phy=tree,names.col=taxa,binvar=",
     colnames(data) [i],")",sep='')
}

for (i in 2:3) {
    print( eval(str2expression(build.expr(i))))
}

К вашему сведению: вот мое sessionInfo, так как вы спросили.

> sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 19.10

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/openblas/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.3.7.so

locale:
 [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8       
 [4] LC_COLLATE=C.UTF-8     LC_MONETARY=C.UTF-8    LC_MESSAGES=C.UTF-8   
 [7] LC_PAPER=C.UTF-8       LC_NAME=C              LC_ADDRESS=C          
 [10] LC_TELEPHONE=C         LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C   

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
[1] compiler_3.6.1 tools_3.6.1   

Когда я набираю? Str2expression, он показывает пакет базы R.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...