R преобразование столбца со строкой как символом, а не как фактором


Мне любопытно поведение transform. Я могу попробовать создать новый столбец как символ, а не как фактор двумя способами:

x <- data.frame(Letters = LETTERS[1:3], Numbers = 1:3)
y <- transform(x, Alphanumeric = as.character(paste(Letters, Numbers)))
x$Alphanumeric = with(x, as.character(paste(Letters, Numbers)))
x
y
str(x$Alphanumeric)
str(y$Alphanumeric)

Результаты "выглядят" одинаково:

> x
  Letters Numbers Alphanumeric
1       A       1          A 1
2       B       2          B 2
3       C       3          C 3
> y
  Letters Numbers Alphanumeric
1       A       1          A 1
2       B       2          B 2
3       C       3          C 3
Но посмотрите внутрь, и только один сработал:
> str(x$Alphanumeric) # did convert to character
 chr [1:3] "A 1" "B 2" "C 3"
> str(y$Alphanumeric) # but transform didn't
 Factor w/ 3 levels "A 1","B 2","C 3": 1 2 3

Я не нашел ?transform очень полезным, чтобы объяснить это поведение - предположительно Alphanumeric был принужден вернуться к тому, чтобы быть фактором - или найти способ остановить его (что-то вроде stringsAsFactors = FALSE для data.frame). Каков самый безопасный способ сделать это? Есть ли подобные ловушки, чтобы остерегаться например, с функциями apply или plyr?

1 2

1 ответ:

Это не столько проблема с transform, Сколько с data.frame s, где stringsAsFactors по умолчанию установлено в TRUE. Добавьте аргумент, что это должно быть FALSE, и вы будете на своем пути:

y <- transform(x, Alphanumeric = paste(Letters, Numbers),
               stringsAsFactors = FALSE)
str(y)
# 'data.frame': 3 obs. of  3 variables:
#  $ Letters     : Factor w/ 3 levels "A","B","C": 1 2 3
#  $ Numbers     : int  1 2 3
#  $ Alphanumeric: chr  "A 1" "B 2" "C 3"

Я обычно использую within вместо transform, и, кажется, у меня нет этой проблемы:

y <- within(x, {
  Alphanumeric = paste(Letters, Numbers)
})
str(y)
# 'data.frame':  3 obs. of  3 variables:
#  $ Letters     : Factor w/ 3 levels "A","B","C": 1 2 3
#  $ Numbers     : int  1 2 3
#  $ Alphanumeric: chr  "A 1" "B 2" "C 3"

Это потому, что он использует подход, аналогичный вашему with подходу: создайте вектор символов и добавьте его (через [<-) в существующий data.frame.

Вы можете просмотреть источник каждого из это делается путем ввода transform.data.frame и within.data.frame в командной строке.


Что касается других ловушек, то это слишком широкий вопрос. Одна вещь, которая приходит на ум прямо Вая, что apply создаст matrix из data.frame, так что все столбцы будут принуждены к одному типу.