2

我有一个数据框,它由几行组成,“名称”列中的值相同,但“距离”列中的值不同。我想删除“名称”中具有相同条目的所有行,只保留距离最小的行。有没有比比较所有行更简单的方法,并在比较它们的“距离”值之前检查它们的“名称”条目是否相同?真实的数据框大约是 14000 行 x 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

4 回答 4

4

name首先,按and对 data.frame 进行排序distance,然后将要保留的行标记为每个名称的第一行:

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

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

结果是

sorted[keep, ]
于 2013-04-03T16:54:02.577 回答
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
于 2013-04-03T16:42:44.367 回答
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)

这是许多方法之一。

于 2013-04-03T16:46:32.977 回答
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
于 2013-04-03T16:58:22.427 回答