Как использовать циклы или Lapply для генерации 100 новых переменных из матрицы?

#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. Спасибо вам, Фил, за такой подробный ответ. Это помогло мне отследить, где я ошибся.