Хотите избежать цикла в r и использовать одну из функций применения
Какую функцию применения следует использовать, чтобы избежать цикла for в приведенном ниже коде? Метки переменных на данный момент являются простыми заполнителями - цель состоит в том, чтобы использовать этот процесс для настройки таблицы кодирования в R для легкого экспорта в SPSS, где кодовая книга готова к открытию при открытии в SPSS. В идеале это упростит мою способность работать в R для моей собственной работы, но будет совместимо с коллегами, которые используют SPSS.
data1 <- read.table(header = TRUE, sep=",",
text = "
SubjectID,Age,WeightPRE,WeightPOST,Height,SES,GenderSTR,GenderCoded
1,45,150,145,5.6,2,m,1
2,50,167,166,5.4,2,f,2
3,35,143,135,5.6,2,F,2
4,44,216,201,5.6,2,m,1
5,32,243,223,6,2,m,1
6,48,165,145,5.2,2,f,2
7,50,132,132,5.3,2,m,1
8,51,110,108,5.1,3,f,2
9,46,167,158,5.5,2,,
10,35,190,200,5.8,1,Male,1
11,36,230,210,6.2,1,m,1
12,40,200,195,6.1,1,f,2
13,45,180,185,5.9,3,f,2
14,52,240,220,6.5,2,m,1
15,24,250,240,6.4,2,M,1
16,35,175,174,5.8,2,F,2
17,51,220,221,6.3,2,m,1
18,43,230,215,2.6,2,m,1
19,36,190,180,5.7,1,female,2
20,44,260,240,6.4,3,male,1
")
var.labels = c(SubjectID="aaa",
Age="Age in Years",
WeightPRE="bbb",
WeightPOST="ccc",
Height="ddd",
SES="eee",
GenderSTR="fff",
GenderCoded="ggg")
for(i in 1:8){
attr(dtab1[[names(var.labels)[i]]],"label") <- var.labels[names(var.labels)[i]]
}
# using the haven package
# this creates SPSS datafile with variable labels
library(haven)
write_sav(dtab1,"out1.sav")
3 ответа
Спасибо тебе lmo
за ваше предложение.
В основном я хотел как можно больше избегать циклов for - но я думаю, что вы правы в этом случае цикл for может быть пригоден для использования. Я просто провел анализ системного времени с помощью microbenchmark
пакет и получил следующее...
library(microbenchmark)
microbenchmark(
data1[] <- lapply(1:8, function(i) {
# assign the label
attr(data1[[names(var.labels)[i]]], "label") <-
var.labels[names(var.labels)[i]]
# return the vector
data1[[names(var.labels)[i]]]
})
)
что привело к:
Unit: microseconds
expr
data1[] <- lapply(1:8, function(i) { attr(data1[[names(var.labels)[i]]], "label") <- var.labels[names(var.labels)[i]] data1[[names(var.labels)[i]]] })
min lq mean median uq max neval
380.291 412.986 638.6603 445.2185 661.102 2863.767 100
и цикл for работает быстрее...
microbenchmark(
for(i in 1:8){
attr(data1[[names(var.labels)[i]]],"label") <- var.labels[names(var.labels)[i]]
}
)
который дал этот анализ времени:
Unit: microseconds
expr
for (i in 1:8) { attr(data1[[names(var.labels)[i]]], "label") <- var.labels[names(var.labels)[i]] }
min lq mean median uq max neval
179.015 197.798 289.9299 209.624 278.7255 1186.783 100
Спасибо за ваш отзыв и рассмотрение моего вопроса.
Что касается цикла, который считается хорошим вариантом, вот небольшое улучшение самого цикла:
for(var in names(var.labels)) {
attr(data1[[var]], "label") <- var.labels[var]
}
Улучшения включают в себя:
- Обобщается на столько ярлыков, сколько необходимо
- Не столкнетесь с проблемами, если вы забудете создать ярлык для любых переменных
- более короткий код и его легче читать (по крайней мере, для меня)
В этом случае for
Цикл, вероятно, лучший способ добавления в этот материал. В качестве примера, вот примерно "лучший" способ добавить в этот материал, используя lapply
:
data1[] <- lapply(1:8, function(i) {
# assign the label
attr(data1[[names(var.labels)[i]]], "label") <-
var.labels[names(var.labels)[i]]
# return the vector
data1[[names(var.labels)[i]]]
})
На мой взгляд, это не так легко прочитать и включает в себя некоторые ненужные растяжения относительно вашего for
петля.