По сути, я хочу перекодировать и переименовать ряд переменных в фрейме данных. Я ищу способ сделать это за один шаг.
Пример в псевдокоде:
require(dplyr)
df <- iris %>% head()
df %>% mutate(
paste0("x", 1:3) = across( # In the example I want to rename
Sepal.Length:Petal.Length, # the variables I've selected
~ .x + 1 # and recoded to "x1" ... "x5"
)
)
df
Желаемый результат:
x1 x2 x3 Petal.Width Species
<dbl> <dbl> <dbl> <dbl> <fct>
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
Может быть, rename_with()
это то, что вы хотите. После этого вы можете управлять этими переименованными столбцами с помощью mutate(across(...))
.
library(dplyr)
df %>%
rename_with(~ paste0("x", seq_along(.x)), Sepal.Length:Petal.Length) %>%
mutate(across(x1:x3, ~ .x * 10))
x1 x2 x3 Petal.Width Species
1 51 35 14 0.2 setosa
2 49 30 14 0.2 setosa
3 47 32 13 0.2 setosa
4 46 31 15 0.2 setosa
5 50 36 14 0.2 setosa
6 54 39 17 0.4 setosa
Если вы хотите манипулировать и переименовывать диапазон столбцов за один шаг, попробуйте аргумент .names
в across()
.
df %>%
mutate(across(Sepal.Length:Petal.Length, ~ .x * 10,
.names = "x{seq_along(.col)}"),
.keep = "unused", .after = 1)
x1 x2 x3 Petal.Width Species
1 51 35 14 0.2 setosa
2 49 30 14 0.2 setosa
3 47 32 13 0.2 setosa
4 46 31 15 0.2 setosa
5 50 36 14 0.2 setosa
6 54 39 17 0.4 setosa
Подсказка: вы можете использовать seq_along()
, чтобы создать последовательность 1, 2, ... вместе с выбранными столбцами, или match()
, чтобы получить позиции выбранных столбцов в данных, то есть .names = "x{match(.col, names(df))}"
.
@PålBjartan смотрите мое обновление. Последняя часть моего ответа управляет рядом столбцов и переименовывает их за один шаг.
Спасибо! Последняя часть - это то, что я искал. Я не знал об аргументе .names
в across()
или о том, что можно добавлять функции в такие кавычки. seq_along()
и match()
действительно очень полезны. Сегодня я узнал три новых вещи. знак равно
Чтобы уточнить проблему: у меня есть фрейм данных с большим количеством данных опроса, с переменными, из которых мне нужно перекодировать и переименовать по-разному. Некоторые из них должны быть перекодированы специально, другие могут быть перекодированы и переименованы аналогичным образом. Отсюда мой вопрос. Я использовал комбинацию rename_with() %>% mutate()
, но из-за огромного количества переменных это несколько загромождено и утомительно. Таким образом, использование .names = "x{seq_along(.col)}"
избавит меня от значительной избыточности.
Вы можете добавить последовательные числа в столбцы n
с одинаковым префиксом следующим образом:
df <- iris %>% head()
n <- 3
colnames(df)[1:n] <- sprintf("x%s",1:n)
выход:
# x1 x2 x3 Petal.Width Species
# 1 5.1 3.5 1.4 0.2 setosa
# 2 4.9 3.0 1.4 0.2 setosa
# 3 4.7 3.2 1.3 0.2 setosa
# 4 4.6 3.1 1.5 0.2 setosa
# 5 5.0 3.6 1.4 0.2 setosa
# 6 5.4 3.9 1.7 0.4 setosa
Из любого непоследовательного количества столбцов на:
n <- c(1,3,5)
colnames(df)[n] <- sprintf("x%s",n)
# x1 Sepal.Width x3 Petal.Width x5
# 1 5.1 3.5 1.4 0.2 setosa
# 2 4.9 3.0 1.4 0.2 setosa
# 3 4.7 3.2 1.3 0.2 setosa
# 4 4.6 3.1 1.5 0.2 setosa
# 5 5.0 3.6 1.4 0.2 setosa
# 6 5.4 3.9 1.7 0.4 setosa
Приведенный ниже код позволяет вам просто вводить номера столбцов в цикл for, не уверенный, что это то, что вам нужно.
require(dplyr)
df <- iris %>% head()
for(i in 1:3){
names(df)[i] <- paste0("x",i)
}
df
Выходы:
x1 x2 x3 Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
Вам не нужен цикл for
или c()
, вы можете просто сделать names(df)[1:3] <- paste0("x",1:3)
Спасибо за ответ! Я все еще довольно новичок здесь! Я убрал c()
, но не мог ли цикл for упростить изменение ввода? IE: нужно изменить один набор аргументов вместо двух?
Добро пожаловать! Конечно, есть случаи, когда циклы могут быть полезны — и чтобы было ясно, что у вас не так, — но R обычно предпочитает векторизацию, когда это возможно. Я не понимаю, как в этом примере цикл for
выиграет от векторизации, но да, у циклов есть некоторые преимущества.
Векторизация более эффективна, чем цикл в R.
Я использовал
rename_with()
в своем текущем коде как дополнительный шаг после перекодирования моих переменных. Однако я надеялся, что будет способ сделать этот процесс одноэтапным.