#r #ggplot2
#r #строка #вектор
Вопрос:
Мне просто интересно, есть ли у R способ преобразовать вектор строк в числа, которые я определяю. Например, скажем, у нас есть вектор следующим образом:
vector <- c("ABC", "DEF", "GHI", "ABC", "GHI", "ABC")
Что я хотел бы сделать, так это вместо того, чтобы иметь элементы ABC
, DEF
, и GHI
в векторе, я бы вместо этого хотел «обменять» их на определенное пользователем число, так что вместо того, чтобы иметь ABC
в векторе I have 1
, вместо DEF
I have 2
, и вместо GHI
I have 3
, так что вектор теперьстановится
vector <- c(1, 2, 3, 1, 3, 1)
Я знаю, что есть функции, которые делают что-то похожее на это, но они не совсем делают то, что я хочу. Например, функция as.numeric(as.factor())
преобразует вектор, заполненный строковыми элементами, в числа, чего я и хочу, но, к сожалению, это не позволяет мне фактически определить, какое строковое значение становится каким числом, что было бы серьезной проблемой, когда используемый мной набор данных изменяется, поскольку числа будут представлять разные строки.
Другой альтернативный метод — использование chartr(old = "ABC", new = "123", x)
функции (где x
находится ваш набор данных), что тоже хорошо, но опять же, основной проблемой является тот факт, что количество «старых» символов должно соответствовать количеству «новых» символов, а также тот факт, что каждый экземпляр буквы будет изменен начисло, такое, что если мы заменим ABC
на 123
then каждый раз B
, когда оно происходит, оно всегда будет заменено на 2
, что не то, что я хочу.
Есть ли у R функция, которая позволит мне менять местами строки в векторе с определяемыми пользователем числами?
РЕДАКТИРОВАТЬ: В частности (для тех, кто хочет сделать это в будущем), я использовал следующую функцию: levels(vector)[levels(vector)=="ABC"] <- "1"
это позволяет вам менять местами отдельные уровни коэффициентов строк с числовым значением и наоборот
Комментарии:
1. используйте
factor
и укажите егоlevels
2. Это именно то, что мне нужно! Спасибо, не могли бы вы вставить это в ответ, чтобы я мог принять это как ответ?
3. В частности (для тех, кто хочет сделать это в будущем), я использовал следующую функцию:
levels(vector)[levels(vector)=="ABC"] <- "1"
это позволяет менять местами отдельные уровни коэффициентов строк с числовым значением и наоборот4. @ThePlowKing — не нужно делать это по одному, просто:
as.numeric(factor(vector, levels=c("ABC","DEF","GHI")))
должен это сделать. Илиc(9,6,3)[factor(vector, levels=c("ABC","DEF","GHI"))]
, если вам нужны абсолютно произвольные числовые значения по вашему выбору, которые не обязательно должны быть последовательными.5. Я понимаю, что первый бит кода в моем комментарии выше по существу
as.numeric(factor())
— разница в том, что вы можете изменитьlevels=
порядок, чтобы явно изменить порядок.
Ответ №1:
1) для подписки при этом не используются пакеты. Опустите unname
, если вы хотите, чтобы выходные данные содержали исходные символьные строки в качестве имен.
map <- c(ABC = 1, DEF = 2, GHI = 3)
unname(map[vector])
## [1] 1 2 3 1 3 1
2) привязка
library(gsubfn)
strapply(vector, ".*", list(ABC = 1, DEF = 2, GHI = 3), simplify = TRUE)
## [1] 1 2 3 1 3 1
3) фактор, который не включает в себя какие-либо пакеты.
as.numeric(format(factor(vector, levels = c("ABC", "DEF", "GHI"), labels = 1:3)))
## [1] 1 2 3 1 3 1
или, если числа всегда равны 1, 2, … тогда это можно упростить до:
as.numeric(factor(vector, levels = c("ABC", "DEF", "GHI")))
## [1] 1 2 3 1 3 1
Если вы оставите levels=
это в стороне, то сначала в алфавитном порядке будет присвоено значение 1 и т.д. так что, если это назначение в порядке, оно еще больше упростится:
as.numeric(factor(vector))
## [1] 1 2 3 1 3 1
4) сопоставление Это также не использует пакеты.
c(1, 2, 3)[match(vector, c("ABC", "DEF", "GHI"))]
## [1] 1 2 3 1 3 1
Если числа всегда равны 1, 2, … тогда это можно упростить до просто:
match(vector, c("ABC", "DEF", "GHI"))
## [1] 1 2 3 1 3 1
5) data.frame Этот работает с фреймами данных. Первые две строки создают фреймы данных, строка nxxt выполняет поиск, а последняя строка гарантирует, что m
они находятся в том же порядке, DF
что и . Последняя строка может быть опущена, если порядок не имеет значения. При этом пакеты не используются.
mapDF <- data.frame(let = c("ABC", "DEF", "GHI"), num = 1:3)
DF <- data.frame(let = vector, order = seq_along(vector))
m <- merge(DF, mapDF, all.x = TRUE, all.y = FALSE)
m[ order(m$order), ]
Существует несколько популярных пакетов, ориентированных на фрейм данных, которые можно использовать здесь вместо двух последних строк выше. order
Столбец не используется в этих решениях и может быть опущен DF
для следующего.
library(dplyr)
DF %>% left_join(mapDF)
library(data.table)
data.table(mapDF)[DF, on = "let"]
library(sqldf)
sqldf("select * from DF left join mapDF using (let)")
Комментарии:
1. Это лучший ответ без вопросов, в частности, первое решение работает так хорошо, и оно намного более интуитивно понятное и простое, поскольку для него не нужны уровни коэффициентов и т. Д. Спасибо за очень подробный ответ и за огромное количество решений, которые вы дали!
Ответ №2:
vector <- c("ABC", "DEF", "GHI", "ABC", "GHI", "ABC")
vector
#[1] "ABC" "DEF" "GHI" "ABC" "GHI" "ABC"
vector=as.factor(vector)
vector
#[1] ABC DEF GHI ABC GHI ABC
vector=as.numeric(vector)
vector
#[1] 1 2 3 1 3 1
Альтернативное решение:
Сопоставьте строки с номерами, определенными пользователем
#map strings to numbers
numbers <- c(1,2,3)
names <- c("ABC", "DEF", "GHI")
#store maping in data frame
df <- data.frame(names, numbers)
df
vector <-as.vector( c("ABC", "DEF", "GHI", "ABC", "GHI", "ABC"))
vector2=c() # the numeric vector
for (i in 1:length(vector)){
id <= which(df$names == vector[i])
vector2 <= c(vector2 ,id)
}
print(vector2)
#[1] 1 2 3 1 3 1
Комментарии:
1. » как.numeric(как.factor()) … это то, что я хочу, но, к сожалению, это не позволяет мне на самом деле определить, какое строковое значение становится каким числом » — OP конкретно заявляет, что они хотят чего-то другого, кроме этого ответа.