TryCatch в цикле

У меня проблемы с запуском оператора 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)

Итак, гипотетически, если x $ k1 имеет тот же тип и во второй строке возникает ошибка, сработает ли ответ Конрада?

MLS 18.02.2019 17:57
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
53
2

Ответы 2

addCol от JMisc, похоже, добавляет одно значение (в документации оно ошибочно называется «константой») в 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обработки недопустимых строк).

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

p = x %>%
    mutate(k1num  = as.numeric(as.character(k1))) %>%
    mutate(sqr = ifelse(is.na(k1num), "NULL", sqrt(k1num)))

@MLS Да, но причина в том, что ваш столбец на самом деле является столбцом строки символов (точнее, коэффициентов), а не чисел. (См. отредактированный ответ)

Konrad Rudolph 18.02.2019 18:00

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

MLS 18.02.2019 18:45

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

Другие вопросы по теме