попробуйте за цикл - PullRequest
       7

попробуйте за цикл

0 голосов
/ 18 февраля 2019

У меня проблемы с запуском оператора tryCatch в цикле for.Я хочу просмотреть каждую строку в моем фрейме данных (x), и если есть ошибка при принятии sqrt данной строки в столбце k1, я хочу, чтобы sqrtd равнялся "NULL", а если нет, то ошибкабыть значением sqrt.

Ниже приведен код, который я пробовал, однако новый столбец sqr для каждой строки имеет "NULL", но только вторая строка должна быть "NULL", поскольку нельзя взятьsqrt("a").

library(Jmisc)
library(dplyr)

x <- data.frame(k1 = c(3,"a",3,4,5), k2 = c(1,NA,NA,4,5), data1 = 1:5)
p <- data.frame(NULL)

for (row in 1:nrow(x)){
  sqrtd <- tryCatch(sqrt(x$k1[row]),error=function(e) sqrtd = "NULL")

  x <- addCol(x,value=c(sqr=sqrtd))
  p <- rbind(p,x) 
}

print(p)

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Каждый вектор может быть только одного типа (например, числовой, логический, символьный).Если вы попытаетесь включить более одного типа в векторное присвоение, вектор будет приведен к самому широкому типу, который может обрабатывать входные данные.Если вы запустите x$k1, вы должны заметить, что результирующий вектор является символьным вектором строк (то есть, "3" "a" "3" "4" "5").Это потому, что "a" является строкой, поэтому весь вектор x$k1 приводится к символу.Получение квадратного корня любого элемента в этом векторе приведет к ошибке, поэтому sqrtd всегда присваивается "NULL".

0 голосов
/ 18 февраля 2019

JMisc's addCol, кажется, добавляет единственное значение (документация вводит в заблуждение его как «константу») в data.frame для всего столбца.В вашем коде вы заменяете существующий столбец после первой итерации новым значением.

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

sqrt_or_null = function (x) {
    tryCatch(sqrt(x), error = function (e) "NULL")
}

p = mutate(x, sqr = lapply(k1, sqrt_or_null))

Однако это оставит вас со столбцом списка, который является громоздким типом данных в data.frame.Причина в том, что данный столбец не из списка может содержать только значения одного типа, но ваша функция возвращает различных типов в зависимости от того, успешно ли выполнена операция: numeric или character.

Вы можете привести результаты:

p = mutate(x, sqr = as.character(lapply(k1, sqrt_or_null)))

… но я предлагаю подумать о лучшем представлении ошибочных значений (таких как NA) или о том, чтобы избежать сбоев перед выполнением этой операции (например,на filter (неверные строки).

Ваш код имеет дополнительную проблему: k1 имеет тип factor, а не numeric.Таким образом, он потерпит неудачу для каждого значения.Сначала вам нужно будет преобразовать значения коэффициентов в числовые значения, что требует двух шагов: преобразование в символьные строки, а затем в числовые значения:

p = x %>%
    mutate(k1num  = as.numeric(as.character(k1))) %>%
    mutate(sqr = ifelse(is.na(k1num), "NULL", sqrt(k1num)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...