2016-04-08 3 views
0

Я хочу создать переменные age10, age20, age30 и т. Д. Для заданного набора данных. Вход для функции add_ages представляет собой кадр данных с именем df, где новые переменные создаются на основе их отношения к существующему возрасту переменной.Создать новые столбцы внутри цикла

df <- data.frame(age=sample(1:100,10,replace=T)) 

add_ages <- function(d){ 
    for(i in seq(10,100,10)){ 
    d[,paste0("age",i)] <<- ifelse(i>=d[,"age"] & d[,"age"]<i+10,1,0) 
    } 
} 

add_ages(d=df) 

Однако, когда я запускаю код выше, я получаю следующее сообщение об ошибке:

Error in d[, paste0("age", i)] <<- ifelse(i >= d[, "age"] & d[, "age"] < : 
    object 'd' not found 

я не уверен, я понимаю, почему d не может быть найден, когда я определяю его быть ДФ , Есть предположения?

ответ

2

Похоже, вы пытаетесь создать фиктивные переменные, используя ваши данные.

Обратите внимание, что для большинства функций моделирования в R это произойдет автоматически на этапе моделирования. Как это работает, используется функция model.matrix().

Вот пример:

< ДФ - data.frame (возраст = образец (1: 100,10, замените = T))

# Create a categorical variable using cut() 
df$agegroup <- cut(df$age, breaks=seq(0, 100, by = 10)) 

Теперь у вас есть категориальная переменная с возрастом группы:

head(df) 
    age agegroup 
1 82 (80,90] 
2 79 (70,80] 
3 99 (90,100] 
4 12 (10,20] 
5 82 (80,90] 
6 66 (60,70] 

Преобразовать в модельной матрице

# Create the model matrix 

model.matrix(~agegroup - 1, df) 
    agegroup(0,10] agegroup(10,20] agegroup(20,30] agegroup(30,40] agegroup(40,50] 
1    0    0    0    0    0 
2    0    0    0    0    0 
3    0    0    0    0    0 
4    0    1    0    0    0 
5    0    0    0    0    0 
6    0    0    0    0    0 
7    0    0    0    0    0 
8    0    1    0    0    0 
9    0    0    0    0    1 
10    0    0    0    0    0 
2

Использовать <- вместо <<-. Использование <<- присваивает вещи в глобальной области, где d не существует. Наконец, верните d.

add_ages <- function(d) { 
    for (i in seq(10,100,10)){ 
    d[,paste0("age",i)] <- ifelse(i>=d[,"age"] & d[,"age"]<i+10,1,0) 
    } 
    d 
} 
df <- add_ages(df) 

Edit:

Если вы действительно хотите делать, чтобы избежать df <- add_ages(df), вы можете сделать следующее:

add_ages <- function() { 
    for (i in seq(10,100,10)){ 
    df[,paste0("age",i)] <<- ifelse(i>=df[,"age"] & df[,"age"]<i+10,1,0) 
    } 
} 

add_ages() 

Я рекомендовал бы против этого, по крайней мере по двум причинам. Во-первых, это вообще не обобщается. На самом деле нет смысла создавать функцию, которая делает это, вам будет лучше просто использовать цикл сразу после создания df, например.

df <- data.frame(age=sample(1:100,10,replace=T)) 
for (i in seq(10,100,10)){ 
    df[,paste0("age",i)] <<- ifelse(i>=df[,"age"] & df[,"age"]<i+10,1,0) 
} 

Во-вторых, функции должны стремиться избегать побочных эффектов. Другими словами, если я вызываю функцию, единственным измененным объектом является то, где я сохраняю вывод. Побочные эффекты, подобные этому, могут показаться безобидными, но если вы должны были написать это как одну из нескольких функций в середине какого-то кода, а затем вернуться к нему через 6 месяцев, вероятно, вы забудете побочные эффекты, которые могут вызвать все виды головных болей.

+0

Есть ли хороший способ вернуть рамку данных, поддерживая исходное имя? Например, без указания df <- d в приведенном выше коде? –

+0

См. Мое редактирование выше. Обратите внимание, что в исходной версии вы не использовали бы 'df <- d', вы бы использовали' df <-add_ages (df) '. – Josh

Смежные вопросы