Проблема связана с областью применения переменных.В этом случае переменная функции fish8
получает назначение в пределах области действия функции.Оригинал fish8
не трогается.См. https://www.r -bloggers.com / dont-run-afoul-of-scoping-rules-in-r / :
Что происходит с << - это то, чтоначинает проходить по дереву среды от дочернего к родительскому, пока не найдет совпадение или не окажется в глобальной (верхней) среде.Это способ начать обход дерева (например, автоматический поиск), но с ужасными последствиями, потому что вы делаете назначение вне текущей области!Будет изменено только первое найденное совпадение, независимо от того, находится оно в глобальной среде или нет. </p>
Возможны следующие варианты:
- Удалите двойное назначение и переназначьте результаты.функции на исходный фрейм данных
remove_empties = function(fish8) {
fish8 <- fish8[!(fish8$x == '' | is.na(fish8$x)), ]
fish8 <- fish8[!(fish8$y == '' | is.na(fish8$y)), ]
}
fish8 <- remove_empties(fish8)
Использование другой переменной в функции, что было бы лучше, чем использование одного и того же имени переменной в двух разных средах.
remove_empties2 = function(fish) {
fish <- fish[!(fish$x == '' | is.na(fish$x)), ]
fish <- fish[!(fish$y == '' | is.na(fish$y)), ]
}
fish8 <- remove_empties2(fish8)
Изменить имя переменной в функции, но глобально присвоить исходную переменную.Мне не нравится этот маршрут:
remove_empties3 = function(fish) {
fish8 <<- fish[!(fish$x == '' | is.na(fish$x))
& !(fish$y == '' | is.na(fish$y)), ]
}
remove_empties3(fish8)
Мой любимый вариант: переназначить пустые строки как
NA
и затем использовать
na.omit()
.Я также отказался бы от вызова функции - это не более чем на одну дополнительную строку, чем вызов функции, и должен выполняться только один раз, поскольку не следует вводить пустые строки:
fish8[fish8==''] <- NA_character_
fish8 <- na.omit(fish8)
Данные:
set.seed(1)
x <- sample(c('',NA_character_, letters[1:5]), 20, replace = T)
y <- sample(c('', NA_character_, letters[6:10]), 20, replace = T)
fish8 <- data.frame(x, y)