#r #loops #lapply
#r #циклы #lapply
Вопрос:
Итак, у меня есть фрейм данных, содержащий 100 различных переменных. Теперь я хочу создать 100 новых переменных, соответствующих каждой переменной в исходном фрейме данных. В настоящее время я пытаюсь использовать циклы и lapply, чтобы найти выход из этого, но пока не очень повезло.
Вот только снимок того, как выглядит фрейм данных (предположим, что мой фрейм данных имеет имя er):
a b c d
1 2 3 4
5 6 7 8
9 0 1 2
и используя каждую из этих 4 переменных, я должен создать новую переменную. Следовательно, всего 4 новых переменных. Моя переменная должна быть такой: предположим, a1 = 0.5 a, b1 = 0.5 b и так далее.
Я пытаюсь использовать следующие два подхода:
for (i in 1:ncol(er)) {
[[i]] <- 0.5 [[i]]
}
и, в качестве альтернативы, я пытаюсь использовать lapply следующим образом:
dep <- lapply(er, function(x) {
x<-0.5 er
}
Но ни одна из них не работает. Кто-нибудь может сообщить мне, в чем проблема с этими кодами, или предложить эффективный код для этого. Я показал здесь только 4 переменные для демонстрации. У меня их около 100.
Ответ №1:
Вы можете напрямую добавить 0,5 (или любое число) к фрейму данных.
er[paste0(names(er), '1')] <- er 0.5
er
# a b c d a1 b1 c1 d1
#1 1 2 3 4 1.5 2.5 3.5 4.5
#2 5 6 7 8 5.5 6.5 7.5 8.5
#3 9 0 1 2 9.5 0.5 1.5 2.5
Комментарии:
1. Огромное спасибо, Ронак! Это работает. Я новичок в программировании, поэтому все еще учусь, но это сработало. 🙂
Ответ №2:
Ответ Ронака обеспечивает наиболее эффективный способ решения вашей проблемы. Я сосредоточусь на том, почему ваши попытки не сработали.
er <- data.frame(a = c(1, 5, 9), b = c(2, 6, 0), c = c(3, 7, 1), d = c(4, 8, 2))
A. для цикла:
for (i in 1:ncol(er)) {
[[i]] <- 0.5 [[i]]
}
Подумайте о том, как R интерпретирует каждый элемент вашего цикла. Он будет переходить от 1 к любому количеству столбцов er
и использовать i
заполнитель, поэтому на первой итерации он будет делать:
[[1]] <- 0.5 [[1]]
Что не имеет смысла, потому что вы вообще не указываете, что вы индексируете. Вместо этого вы хотели бы:
for (i in 1:ncol(er)) {
er[[i]] <- 0.5 er[[i]]
}
Здесь каждая итерация будет означать «присвоить i-му столбцу er, i-му столбцу er 0,5». Если вы хотите дополнительно добавить, что хотите создать новые переменные, вы должны сделать следующее (что несколько похоже на ответ Ронака, только менее эффективно):
for (i in 1:ncol(er)) {
er[[paste0(names(er)[i], "1")]] <- 0.5 er[[i]]
}
В качестве примечания, предпочтительнее использовать seq_along(er)
вместо 1:ncol(er)
.
B. lapply:
dep <- lapply(er, function(x) {
x<-0.5 er
}
При создании функции, независимо от того, что вам нужно, укажите, что вы хотите вернуть, вызвав ее. Здесь function(x) { x 0.5 }
достаточно указать, что вы хотите вернуть переменную 0,5. Поскольку lapply()
возвращает список (название функции сокращенно от «применить список»), вы захотите использовать as.data.frame()
:
as.data.frame(lapply(er, function(x) { x 0.5 }))
Однако это не изменяет имена переменных, и здесь нет простого эффективного способа изменить это:
dep <- as.data.frame(lapply(er, function(x) { x 0.5 }))
names(dep) <- paste0(names(dep), "1")
cbind(er, dep)
a b c d a1 b1 c1 d1
1 1 2 3 4 1.5 2.5 3.5 4.5
2 5 6 7 8 5.5 6.5 7.5 8.5
3 9 0 1 2 9.5 0.5 1.5 2.5
C. Другим способом было бы использование dplyr
синтаксиса, который является более элегантным и читаемым:
library(dplyr)
mutate(er, across(everything(), ~ . 0.5, .names = "{.col}1"))
Комментарии:
1. Спасибо вам, Фил, за такой подробный ответ. Это помогло мне отследить, где я ошибся.