2013-04-03 50 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 
相关问题