2014-04-06 90 views
0

我有一個數據幀。我想計算每一行距離給定行的「遠」程度。讓我們考慮第一排。讓數據幀如下:計算數據幀中行之間的差異

> sampleDF 

    X1 X2 X3 
    1 5 5 
    4 2 2 
    2 9 1 
    7 7 3 

我希望做的是以下幾點:

  1. 計算&他人的第1行的區別:sampleDF[1,]-sampleDF[2,]
  2. 只考慮絕對值: abs(sampleDF[1,]-sampleDF[2,])
  3. 計算新形成的差異數據幀之和:rowSums(newDF)

現在要對整個數據幀執行此操作。

newDF <- sapply(2:4,function(x) { return (abs(sampleDF[1,]-sampleDF[x,]));})

這在結果產生的一個問題是轉置列表。

> class(newDF) 
[1] "data.frame" 
> rowSums(newDF) 
Error in base::rowSums(x, na.rm = na.rm, dims = dims, ...) : 
    'x' must be numeric 
> newDF 
    X1 X2 X3 
1 3 3 3 
2 1 4 4 
3 6 2 2 
> 

拼圖1:我爲什麼會得到這個錯誤。因此,

newDF <- as.data.frame(t(sapply(2:4,function(x) { return (abs(sampleDF[1,]-sampleDF[x,]));})))

但在計算rowSums產生了另一個問題?我注意到newDF [1,1]是一個不是數字的列表&。是因爲那個嗎?我怎樣才能確保轉換的結果是一個簡單的數字數據框?

於是我着手建立一個全球性的數據幀&函數內修改:

sapply(2:4,function(x) { newDF <<- as.data.frame(rbind(newDF,abs(sampleDF[1,]-sampleDF[x,])));})

> newDF 
    X1 X2 X3 
2 3 3 3 
3 1 4 4 
4 6 2 2 
> rowSums(outDF) 
2 3 4 
9 9 10 
> 

這是符合市場預期。

拼圖2:有沒有更清晰的方法來實現這一目標?我怎樣才能做到這一點在數據框中的每一行(上面顯示的僅僅是從第1行「距離」,也需要爲其他行做這個)?運行一個循環是唯一的選擇?

回答

1

爲了把它的話,你想計算曼哈頓距離:

dist(sampleDF, method = "Manhattan") 
# 1 2 3 
# 2 9  
# 3 9 10 
# 4 10 9 9 

關於您的實現,我認爲問題是,你的內部函數返回一個data.frame時,它應該返回一個數字矢量。做return(unlist(abs(sampleDF[1,]-sampleDF[x,])))應該修復它。

+0

非常感謝你的澄清。雖然我知道我必須計算一段距離,但並沒有讓我檢查R是否有計算距離的東西。函數中的unlist也幫助解決了我的問題。現在看看我是否可以使用自定義方法來計算距離。 –