【问题标题】:Extracting rows from selected column in repeated/grouped data从重复/分组数据中的选定列中提取行
【发布时间】:2014-09-14 04:59:27
【问题描述】:

我有一个下面给出的数据框 (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 &lt;- 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)"))

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

【问题讨论】:

    标签: r dataframe


    【解决方案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
    

    【讨论】:

    • 非常感谢您的回答 - 完成了这项工作!
    【解决方案2】:

    如果您的数据集中的每一行都是唯一的,您只需使用 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
    

    【讨论】:

    • 感谢您的回复。我无法复制你的结果——我认为 setDT 有问题——这个函数还没有定义。我肯定会阅读更多有关数据表的信息,这似乎是一个非常有用的包。
    • @John,你需要先安装/加载包data.tablesetDT 没有理由不工作
    • 在运行该代码之前,我已经安装了这个包 - 仍然是同样的问题。包肯定已经安装了——我已经检查过了。
    • @John,你library(data.table)了吗?你收到什么错误?您也可以将setDT(B) 替换为data.table(B)(虽然效率较低)
    • 可能你有一个旧版本的data.table 包。要么更新它,要么只是将setDT(B) 切换到data.table(B)
    猜你喜欢
    • 1970-01-01
    • 2014-12-10
    • 1970-01-01
    • 2020-11-21
    • 2018-09-29
    • 2011-12-11
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多