2015-10-05 149 views
0

我正在嘗試編寫一個函數,當我調用它時,它將向數據框中添加一個新列,而不進行任何明確的賦值。 即我只是想調用帶參數的功能,並把它修改數據幀:從R中的函數內修改全局數據

input_data: 
x y 
1 2 
2 6 


column_creator<-function(data,column_name,...){ 
data$column_name <- newdata ...} 

column_creator(input_data,new_col,...) 

x y new_col 
1 2 5 
2 6 9 

至於反對:

input_data$new_col <- column_creator(input_data,new_col,...) 

但是這樣做在函數內部分配不修改全局變量。

我正在通過讓函數返回一個賦值語句(下面的函數中的temp)來解決這個問題,但是有沒有另外一種方法來做到這一點?

這裏是我的函數供參考,它應該在名稱爲dummy_name的情況下在提供的開始日期和結束日期之間創建一個1的列。

dummy_creator<-function(data,date,dummy_name,start,end){ 

    temp<-paste(data,"['",dummy_name,"'] <- ifelse(",data,"['",date,"'] > as.Date (","'" , start,"'" , ", format= '%Y-%m-%d') & ",data,"['",date,"'] < as.Date(", "'", end,"'" ,",format='%Y-%m-%d') ,1,0)",sep="") 
    print(temp) 
    return() 
} 

感謝

我也試過:

dummy_creator<-function(data,date,dummy_name,start,end){ 

    data[dummy_name] <<- ifelse(data[,date] > as.Date (start, format= "%Y-%m-%d") & data[,date] < as.Date(end,format="%Y-%m-%d") ,1,0) 

    } 

但是,嘗試給了我錯誤object of type closure is not subsettable

+4

你可以用超賦值運算符'<<嘗試 - '。 – RHertel

+0

@RHertel沒有沒有工作,它給了我類型閉包的錯誤對象不是子集表單,當不存在東西時就會出現。 – user124123

回答

2

修改傳遞給函數的全局數據或數據通常是一個糟糕的主意:R對象是不可變的,在函數中使用技巧修改它們會打破用戶的期望,並且使得更難推理程序的狀態。

這是很好的形式返回,而不是修改的對象:

input_data = column_creator(input_data, new_col, …) 

這就是說,你有幾種選擇。一般來說,R有幾個機制允許修改對象。我建議你看看這個R6 classes

您也可以使用non-standard evaluation來捕獲傳遞的對象並在來電者的站點修改它。但是,這是不可取的。我在這裏發佈一個這樣的例子,因爲這個機制很有趣,值得了解,但我會重申,你不應該在這裏使用它。

function (df, new_col, new_data) { 
    # Get the unevaluated expression representing the data frame 
    df_obj = substitute(df) 
    new_col = substitute(new_col) 
    # Ensure that the input is valid 
    stopifnot(is.name(df_obj)) 
    stopifnot(is.name(new_col)) 
    stopifnot(is.data.frame(df)) 

    # Add new column to data frame 
    df[[deparse(new_col)]] = new_data 
    # Assign back to object in caller scope 
    assign(deparse(df_obj), df, parent.frame()) 
    invisible(df) 
} 
test = data.frame(A = 1 : 5, B = 1 : 5) 
column_creator(test, C, 6 : 10) 
test 
# A B C 
# 1 1 1 6 
# 2 2 2 7 
# 3 3 3 8 
# 4 4 4 9 
# 5 5 5 10