2013-04-03 48 views
1

我有由具有在列「距離」在列「姓名」相同的值,但不同的值的若干行的一個數據幀。我想刪除「名稱」中具有相同條目的所有行,只保留距離最小的條目。有沒有比比較所有行更簡單的方法,並檢查他們的「名稱」條目是否相同,然後再比較其「距離」值?真正的數據框大約是14000行x 14列。 我看了一個答案,但沒有發現任何東西,所以我會任何幫助非常感謝!的R - 比較並刪除與數據幀相同的列值的行,同時保持其中的一個

這將是原始數據幀:

 name  distance number 
[1,] "apple" "2.5" "4" 
[2,] "banana" "3"  "6" 
[3,] "apple" "1"  "2" 
[4,] "satsuma" "4"  "8" 
[5,] "satsuma" "7.5" "1" 
[6,] "melon" "3"  "3" 
[7,] "satsuma" "1"  "6" 

這是我想要得到什麼(不一定是按照這個順序):

 name  distance number 
[1,] "banana" "3"  "6" 
[2,] "apple" "1"  "2" 
[3,] "melon" "3"  "3" 
[4,] "satsuma" "1"  "6" 
+0

這不是一個數據框,而是一個矩陣。 –

回答

4

首先,排序namedistance的data.frame,然後標記行,以保持作爲第一批爲每名:

sorted <- dat[order(dat$name, dat$distance), ] 

keep <- c(TRUE, head(sorted$name,-1) != tail(sorted$name,-1)) 

結果是

sorted[keep, ] 
+0

我認爲我們有一個贏家。 –

+0

是的,這可能是最快的方法。 +1 –

+0

非常感謝,它的工作原理也很快! – atreju

2

您可以使用aggregatemerge像低於

DF <- read.table(text='name  distance number 
apple 2.5 4 
banana 3  6 
apple 1  2 
satsuma 4  8 
satsuma 7.5 1 
melon 3  3 
satsuma 1  6', header=TRUE) 

merge(DF, aggregate(distance ~ name, data = DF, min)) 
##  name distance number 
## 1 apple  1  2 
## 2 banana  3  6 
## 3 melon  3  3 
## 4 satsuma  1  6 
+0

不錯的做法。永遠不會想到這一點。 +1 –

1

幾個指針開始:

讓你的數據容易給別人儘可能地閱讀。 dput(head(your_data))是一個很好的方法來做到這一點。和你的兩個數據是一個矩陣,而不是一個數據幀,所以你必須限制最少的數據類型爲字符,因此所有數據是一個字符。我認爲將它存儲爲data.frame在這裏更好,因爲您有混合的數據類型。所以,馬上我把數據作爲數據框讀取,並確保距離列是數字。

dat <- read.table(text=' 
name  distance number 
"apple" "2.5" "4" 
"banana" "3"  "6" 
"apple" "1"  "2" 
"satsuma" "4"  "8" 
"satsuma" "7.5" "1" 
"melon" "3"  "3" 
"satsuma" "1"  "6"', header=T) 

dat$distance <- as.numeric(dat$distance) 


#split by grouping variable 
splitdat <- split(dat, dat$name) 

#find the minimum distance and index that 
out <- lapply(splitdat, function(x) { 
    x[which.min(x$distance), ] 
}) 

#put it all back together as a data frame 
data.frame(do.call(rbind, out), row.names=NULL) 

這是很多方法之一。

+0

有用的newb-advice。 lapply(split(..,..))範式與我用過的'by'非常相似。 –

+0

感謝您的回答和建議!這是我的第一個問題,我試圖儘可能通用(我的真實數據是數據框而不是矩陣)。 – atreju

1

我看到@ geektrader的聚合合併方法,但不知道合併可能是CPU和內存密集型:

do.call(rbind, by(DF, DF['name'], function(d) d[which.min(d$distance), ])) 
      name distance number 
apple  apple  1  2 
banana banana  3  6 
melon  melon  3  3 
satsuma satsuma  1  6 
相關問題