«недопустимый аргумент envir типа« символ »при использовании» с «внутри» apply - PullRequest
1 голос
/ 07 июля 2019

Я применяю два условия к каждой строке в кадре данных trades1 (в основном сравнивая каждую строку с каждой строкой в ​​одном столбце).Вектор conditions должен состоять из 1, если оба условия выполнены, и 0 в противном случае.

Пример данных:

  order     date         time           ms price dir amount    hour index i
1 FUT-3 14.02.06 10:00:00.567 1.950535e+16 66.97 BUY      1 5418154     1 1
2 FUT-3 14.02.06 10:00:00.574 1.950535e+16 66.97 BUY      1 5418154     2 2
3 FUT-3 14.02.06 10:00:00.577 1.950535e+16 66.97 BUY      1 5418154     3 3
4 FUT-3 14.02.06 10:00:00.585 1.950535e+16 66.97 BUY      1 5418154     4 4
5 FUT-3 14.02.06 10:00:00.587 1.950535e+16 66.97 BUY      1 5418154     5 5
6 FUT-3 14.02.06 10:00:00.594 1.950535e+16 66.97 BUY      1 5418154     6 6

Код:

conditions <- apply(trades1, 1, function(x) with(x, as.integer(ms - trades$ms == 1e+6 & price/trades1$price >= 1)))

I 'мы проверили, что trades1 является кадром данных и что столбцы являются числовыми.Я получаю ошибку:

Error in eval(substitute(expr), data, enclos = parent.frame()) : 
  invalid 'envir' argument of type 'character'

В случае, если проблема не в аргументе данных, а в размещении with внутри apply, я был бы признателен за предложения о том, как решить эту проблему другим способом..

Ответы [ 2 ]

5 голосов
/ 07 июля 2019

Первое, что делает apply, это конвертирует свой аргумент в матрицу.Как только это будет сделано, with больше не будет работать.

Если вы хотите перебрать строки (вы уверены , это лучшее решение?), Используйте простой старый for цикл или lapply над вектором номеров строк:

lst <- lapply(seq_len(nrow(trades1)), function(row) { with(trades1[row, ], ...) } )
do.call(rbind, lst)
2 голосов
/ 07 июля 2019

Как уже упоминалось @Hong Ooi apply преобразует кадр данных в матрицу и, следовательно, все ваши числа преобразуются в символы. Вы можете исправить цикл apply, выполнив команду

apply(df, 1, function(x) as.integer(any(as.numeric(x["ms"]) - df$ms == 1e+6 & 
                                    as.numeric(x["price"])/df$price >= 1)))

Тем не менее, я думаю, что лучшим подходом здесь будет использование mapply, так как вы хотите проверить условия для price и ms.

as.integer(mapply(function(x, y) 
          any(x - df$ms == 1e+6 & y/df$price >= 1),df$ms, df$price))

Аналогичный подход с использованием data.table

library(data.table)
setDT(df)[, ans := as.integer(any(ms - df$ms == 1e+6 & 
                                  price/df$price >= 1)), by = seq_len(nrow(df))]

и tidyverse

library(dplyr)
library(purrr)

df %>%
   mutate(ans = map2(ms, price, 
               ~as.integer(any(.x - df$ms == 1e+6 & .y/df$price >= 1))))
...