2013-04-24 19 views
0

我是新來編寫函數,我不知道從哪裏開始。以下是本例中名爲m1的數據框的子集。我想編寫一個函數,通過數據集並通過數字提取長度和深度信息。例如,如果它遇到數字1,它將獲取長度和深度,並將它們插入新數據幀或矢量的第一行。如果數字等於2等,那麼它也會這樣。編寫用戶定義函數

 length number depth 
[1,] 109  1 10 
[2,] 109  1 10 
[3,] 109  1 10 
[4,] 109  1 10 
[5,] 109  1 10 
[6,] 109  1 10 
[7,] 109  1 10 
[8,] 109  1 10 
[9,] 109  1 10 
[10,] 109  1 10 
[11,] 109  1 10 
[12,] 109  1 10 
[13,] 107  2 10 
[14,] 107  2 10 
[15,] 107  2 10 
[16,] 107  2 10 
[17,] 107  2 10 
[18,] 107  2 10 
[19,] 107  2 10 
[20,] 107  2 10 

這是在寫一個函數試圖獲得上述的輸出,如果數量等於1

length.fun=function(x) 
{ 
    lengths=numeric() 
    depth=numeric() 
    if (x[2]==1) 
    { 
    lengths=x[1] 
    depth=x[3] 
    } 
    return(cbind(depth,lengths)) 
} 

length.fun(m1) 

但是,我得到的作爲輸出是這樣的:

length.fun(m1) 
    depth lengths 

任何幫助,非常感謝。 感謝

+0

它看起來不像data.frame。 class(m1)'的輸出是什麼? – Roland 2013-04-24 14:17:35

+0

你的目標是什麼?帶有兩行的data.frame,一個用於「深度」,一個用於「長度」。或者多行,每個'''中的每個唯一元素都有一行。或者對於多個行,'number'中的每個唯一元素有兩個,''長度'一個,'深度'一個?請稍微詳細一點。 – 2013-04-24 14:25:18

+0

user1997414,我的理解是你想爲每個數值創建單獨的數據幀(或矩陣)。這是真的。如果這是真的,也許你可以提供一些關於你爲什麼要這樣做的背景信息? – Arhopala 2013-04-24 14:34:19

回答

3

編輯:

從您發表評論我明白你想要得到的唯一行。幸運的是,只爲這一個功能:

unique(m1) 

#  length number depth 
# [1,]  109  1 10 
# [13,] 107  2 10 

unique(m1)[,-2]會給你只有兩列。使用as.data.frame將矩陣轉換爲data.frame。


m1是一個矩陣。矩陣只是一個具有維度屬性的向量。 m1[2]爲您提供向量中的第二個值,即109。因此,您的if條件是FALSEcbind您的函數中的空向量。

這你想要做什麼:

m1[m1[,2]==1,c(1,3)] 

你應該R.

矩陣子集讀了您可以使用調試功能來檢查發生了什麼。下面是一個示例:

首先在函數中使用browser插入斷點。

length.fun=function(x) 
{ 
    lengths=numeric() 
    depth=numeric() 
    if (x[2]==1) 
    {browser("1") 
    lengths=x[1] 
    depth=x[3] 
    } 
    browser("2") 
    return(cbind(depth,lengths)) 
} 

現在使用trace調用函數。

trace(length.fun(m1)) 

您將得到一個提示,允許您檢查變量的狀態。

> trace(length.fun(m1)) 
Called from: length.fun(m1) 
Browse[1]> browserText() 
[1] "2" 
Browse[1]> lengths 
numeric(0) 
Browse[1]> Q 

如您所見,第一個到達的斷點是第二個斷點。因此,if構造的條件是FALSE,並且裏面的代碼從未執行過。這也得到了lengths的確認。

2

編輯:從數據是以矩陣還是以數據框形式表示的問題不清楚。

如果它是一個數據幀,那麼x [2]是一個長度大於1的向量。因此,你的狀況只會測試第一個元素。如果它是矩陣,請參閱@Roland的解釋。

作爲初學者,在編寫函數時,建議從「裏外」走。也就是說,不要先寫功能。從簡單的代碼片斷開始。看看m1[2]給出了什麼。查看m1[2]==1給出了什麼布爾值(無論這是表達式是TRUE還是FALSE)。然後嘗試運行條件。只有當代碼的主要/關鍵部分按預期工作時,手頭上的特定數據纔會圍繞該代碼包裝函數。

您試圖實現的特定功能必須遍歷第2列中的所有值。因此,需要某種循環,例如, forapply

+0

(-1)'x [2]'是長度爲1的向量。 – Roland 2013-04-24 14:07:44

+0

@Roland在矩陣中,是的。在data.frame中,不。 m1是一個data.frame。自己檢查一下。 – 2013-04-24 14:11:54

+0

根據顯示的輸出,'m1'是一個矩陣。如果它是一個data.frame,他們會從函數中得到警告。 – Roland 2013-04-24 14:13:48

1

您可以使用拆分功能將您的數據框拆分爲單獨的數據框列表。如果您的數據幀被稱爲富則:

foo.split<-split(foo[,c('length','depth')],foo$number) 

鑑於此列表中,您可以命名列表中的每個元素,提取元素等

注意,數據幀這隻作品。如果有矩陣,可以使用data.frame()函數將其轉換爲數據幀。

+0

在他們的問題中,他們展示了一個矩陣...... – Roland 2013-04-24 14:12:19

+0

Roland,他寫道:「以下是本例中名爲m1的數據框的子集」。 – Arhopala 2013-04-24 14:17:24

+0

他們顯然是初學者,現在可能不是,他們實際上有什麼。 – Roland 2013-04-24 14:19:53