R - 比较并删除数据框中具有相同列值的行,同时保留其中一个

时间:2013-04-03 16:34:52

标签: r dataframe

我的数据框由“name”列中具有相同值的多行组成,但“distance”列中的值不同。我想删除“name”中具有相同条目的所有行,除了距离最小的行。有没有比比较所有行更简单的方法,并在比较它们的“距离”值之前检查它们的“名称”条目是否相同?实际数据帧大约是14000行×14列。 我已经找到了答案,但还没有找到任何答案,所以我非常感谢任何帮助!

这将是原始数据框:

     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"   

4 个答案:

答案 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, ]

答案 1 :(得分: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

答案 2 :(得分: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)

这是众多方法之一。

答案 3 :(得分: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