Почему функция sub (…) полностью искажает мой фрейм данных?

#r #gsub

#r #gsub

Вопрос:

как ни странно, я не наткнулся на это во время просмотра онлайн. По сути, я пытаюсь применить функцию sub (…) к простому фрейму данных. Пожалуйста, обратитесь к следующему примеру:

 x <- data.frame(name=c("Hans", "Dieter", "Peter"), age=c(25,26,27))
data <- data.frame(sub("e", "a", x)) #subbing an e for an a
 

Вывод полностью изменяет фрейм данных, первая строка теперь содержит:

c («Hans», «Diater», «Peter»)

Второй:

c(25, 26, 27)

Может кто-нибудь быть таким добрым и помочь мне, чтобы я мог понять, что происходит? Большое спасибо!

Комментарии:

1. Может быть , вы имели в виду x$name <- sub("e", "a", x$name) . Он sub был применен ко всему x фрейму данных вместо столбца ‘name’, поскольку sub ожидает его x аргумент as vector . Вы можете проверить ?sub для получения дополнительной информации

2. Большое вам спасибо, теперь все получилось! Итак, если я не отмечу точный столбец, функция sub (…) преобразует мой data.frame в вектор? Спасибо еще раз

3. Data.frame — это a list с элементами ( column — обычно вектор) одинаковой длины. A list отличается от a vector . Согласно ?sub , он ожидает вектор в качестве входных данных. Как правило, я бы посмотрел документацию функции, прежде чем применять ее, чтобы понять, что функция ожидает в качестве входных данных

Ответ №1:

sub() Функция предназначена не для работы с целыми фреймами данных, а только с отдельными векторами.

Это должно сработать:

 x <- data.frame(name=c("Hans", "Dieter", "Peter"), age=c(25,26,27))
x
#>     name age
#> 1   Hans  25
#> 2 Dieter  26
#> 3  Peter  27

library(tidyverse)
data <- x %>% mutate(name = str_replace(name, "e", "a")) #subbing an e for an a
data
#>     name age
#> 1   Hans  25
#> 2 Diater  26
#> 3  Pater  27
 

или немного короче без каналов

 data <- mutate(x, name = str_replace(name, "e", "a"))
 

Создано 2021-01-05 пакетом reprex (версия 0.3.0)

Ответ №2:

Вы можете использовать базовый подход R lapply для повторного построения фрейма данных с измененными значениями:

 ## With regex enabled:
df[] <- lapply(df, gsub, pattern='a', replacement='e')
## Without regex, fixed string replacement:
df[] <- lapply(df, gsub, pattern='a', replacement='e', fixed=TRUE)
 

Смотрите демонстрацию R онлайн, вывод:

     name age
1   Hens  25
2 Dieter  26
3  Peter  27
 

ПРИМЕЧАНИЕ: поскольку age в результате тип столбца изменяется на char , вы должны вернуть тип столбца обратно к числовому:

 df$age <- as.numeric(df$age)
 

Если вы хотите выполнить замены только для всех столбцов типа char , используйте

 df <- data.frame(name=c("Hans", "Dieter", "Peter"), age=c(25,26,27), stringsAsFactors=FALSE)
chr_idx <- sapply(df, is.character)
df[chr_idx] <- lapply(df[chr_idx], gsub, pattern='a', replacement='e', fixed=TRUE)
 

Посмотрите эту демонстрацию R.

Комментарии:

1. Спасибо за этот очень полезный ответ. Что именно указывает значение fixed=TRUE ? Я пытался найти это в руководстве, но на самом деле не понимаю. Насколько я вижу, результат тот же

2. @chrtpmdr fixed=TRUE Опция отключает функцию регулярных выражений, аргумент шаблона ищется как литеральная строка. Это значительно ускоряет процесс замены.