2016-04-08 75 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無法找到,當我定義它是DF 。有什麼想法嗎?

回答

2

這聽起來像你正試圖使用​​你的數據創建虛擬變量。

請注意,對於R中的大多數建模函數,這將在建模步驟中自動發生。它的工作方式是使用model.matrix()函數。

下面是一個例子:

DF < - 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) 

編輯:

如果你真的想避免做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