我的数据框由“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"
答案 0 :(得分:4)
首先,按name
和distance
对data.frame进行排序,然后将行标记为每个名称的第一行:
sorted <- dat[order(dat$name, dat$distance), ]
keep <- c(TRUE, head(sorted$name,-1) != tail(sorted$name,-1))
结果是
sorted[keep, ]
答案 1 :(得分:2)
您可以使用aggregate
和merge
,如下所示
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