从重复/分组数据中的选定列中提取行

时间:2014-05-10 21:40:23

标签: r dataframe

我有一个下面给出的数据框(B),其中包含各种ID(x_1)的重复条目。对于x_1中的每个id,我有兴趣在第二列(z_1)中提取具有最小值(以及它们的重复)的行。例如,对于A1,我想提取第5行和第6行。我还想保留z_1列下的值不超过1的行 - 例如,所有其他除A1和B10之外的条目应包含在输出中。

x_1 <- c("A1", "A1", "A1", "A1", "A1", "A1", "B10", "B10", "B10","B10", "B500", "B500", "C100", "C100", "C100", "D40", "D40", "G100", "G100")
z_1 <- c(rep(1.87, 2), rep(1.56, 2), rep(1.15, 2), rep(1.60, 2), rep(1.44, 2), rep(1.34, 2), rep(1.50, 3), rep(1.90, 2), rep(1.59, 2))
z_2 <- c( c(0.5, 1, 0.5, 1, 0.5, 1), c(0.2, 0.4, 0.2, 0.4), c(0.3, 0.6), c(0.6, 1.2, 1.8), c(0.25, 0.5), c(0.15, 0.3))

这是数据框:

B <- data.frame(x_1, z_1, z_2)

x_1  z_1  z_2
 A1  1.87 0.50
 A1  1.87 1.00
 A1  1.56 0.50
 A1  1.56 1.00
 A1  1.15 0.50
 A1  1.15 1.00
B10  1.60 0.20
B10  1.60 0.40
B10  1.44 0.20
B10  1.44 0.40
B500 1.34 0.30
B500 1.34 0.60
C100 1.50 0.60
C100 1.50 1.20
C100 1.50 1.80
D40  1.90 0.25
D40  1.90 0.50
G100 1.59 0.15
G100 1.59 0.30

以下是我想获得的结果:

y_1  d_1  d_2
A1   1.15 0.50
A1   1.15 1.00
B10  1.44 0.20
B10  1.44 0.40
B500 1.34 0.30
B500 1.34 0.60
C100 1.50 0.60
C100 1.50 1.20
C100 1.50 1.80
D40  1.90 0.25
D40  1.90 0.50
G100 1.59 0.15
G100 1.59 0.30

只是补充说我已经尝试了一些我从其他类似的帖子中找到的东西,但这些都没有给出所需的输出:

aggregate(grouped_B$x_1, by = list(grouped_B$z_1), min)
do.call("rbind", by(B, B$x_1, function(x) x[which.min(unique(x$z_1)), ]))

还要补充一点,我正在处理的数据框是分组数据:

grouped_B <- groupedData(z_1 ~ z_2 | x_1,      
                         data = B, FUN = mean,
                         labels = list( x = "duration",
                         y = "height"), units = list("(years)"))

我非常感谢任何有用的提示/代码。

2 个答案:

答案 0 :(得分:1)

如果数据集中的每一行都是唯一的,则只需使用data.table

即可
library(data.table)
DT <- setDT(B)[, min(z_1), by = c("x_1", "z_2")]
setnames(DT, 1:3, c("y_1", "d_2", "d_1"))
#      y_1  d_2  d_1
#  1:   A1 0.50 1.15
#  2:   A1 1.00 1.15
#  3:  B10 0.20 1.44
#  4:  B10 0.40 1.44
#  5: B500 0.30 1.34
#  6: B500 0.60 1.34
#  7: C100 0.60 1.50
#  8: C100 1.20 1.50
#  9: C100 1.80 1.50
# 10:  D40 0.25 1.90
# 11:  D40 0.50 1.90
# 12: G100 0.15 1.59
# 13: G100 0.30 1.59

如果它不是唯一的,可以做

DT <- setDT(B)[, list(d_1 = z_1[grep(min(z_1), z_1)],
                d_2 = z_2[grep(min(z_1), z_1)]), by = c("x_1")]

#      x_1  d_1  d_2
#  1:   A1 1.15 0.50
#  2:   A1 1.15 1.00
#  3:  B10 1.44 0.20
#  4:  B10 1.44 0.40
#  5: B500 1.34 0.30
#  6: B500 1.34 0.60
#  7: C100 1.50 0.60
#  8: C100 1.50 1.20
#  9: C100 1.50 1.80
# 10:  D40 1.90 0.25
# 11:  D40 1.90 0.50
# 12: G100 1.59 0.15
# 13: G100 1.59 0.30

答案 1 :(得分:1)

基础R也很简单:

result <- merge(B,aggregate(z_1~x_1,B,min))
result
#     x_1  z_1  z_2
# 1    A1 1.15 0.50
# 2    A1 1.15 1.00
# 3   B10 1.44 0.20
# 4   B10 1.44 0.40
# 5  B500 1.34 0.30
# 6  B500 1.34 0.60
# 7  C100 1.50 0.60
# 8  C100 1.50 1.20
# 9  C100 1.50 1.80
# 10  D40 1.90 0.25
# 11  D40 1.90 0.50
# 12 G100 1.59 0.15
# 13 G100 1.59 0.30