【问题标题】:how to subset rows in specific columns based on minimum values in individual columns in a dataframe using R如何使用 R 根据数据框中各个列中的最小值对特定列中的行进行子集化
【发布时间】:2021-03-28 09:49:29
【问题描述】:

我们有一个包含 1000 行多列的数据框。示例数据框如下所示

df1 <- data.frame(X = c(7.48, 7.82, 8.15, 8.47, 8.80, 9.20, 9.51, 9.83, 10.13, 10.59, 7.59, 8.06, 8.39, 8.87, 9.26, 9.64, 10.09, 10.48, 10.88, 11.45), 
              Y = c(49.16, 48.78, 48.40, 48.03, 47.65, 47.24, 46.87, 46.51, 46.15, 45.73, 48.70, 48.18, 47.72, 47.20, 46.71, 46.23, 45.72, 45.24, 44.77, 44.23), 
              ID = c("B_1", "B_1", "B_1", "B_1", "B_1", "B_1", "B_1", "B_1", "B_1", "B_1", "B_1_2", "B_1_2", "B_1_2", "B_1_2", "B_1_2", "B_1_2", "B_1_2", "B_1_2", "B_1_2", "B_1_2"), 
              TI = c(191.31, 191.35, 191.39, 191.44, 191.48, 191.52, 191.56, 191.60, 191.64, 191.69, 1349.93, 1349.97, 1350.01, 1350.05, 1350.09, 1350.14, 1350.18, 1350.22, 1350.26, 1350.30),
              X0 = c(0.172, 0.344,0.846,1.335,1.838,2.410,2.89,3.37,3.842,4.46,0.361,0.983,1.545,2.241,2.86,3.47,4.15,4.77,5.388,6.164),
              V2 = c(1.154,0.644,0.141,0.348,0.851,1.423,1.9059,2.3875,2.856,3.475,0.771,0.224,0.596,1.262,1.883,2.493,3.168,3.786,4.402,5.177))

在数据框“df1”中,我们希望分别根据第 5 列和第 6 列中的最小值按 ID 对列中的行进行子集化。

例如,在数据框“df1”中,“X0”列中的 ID“B_1”,0.172 是最小值,0.140 是相同 ID 的“V2”列中的最小值。所以我们想从 1:4 列中提取第 1 行和第 3 行以及它们对应的 df1 数据帧的 X0th 和 V2th 值,如下图所示。对于 ID“B_1_2”也是如此。像变量“X0”、“V2”变量,我们的数据集中有 20 多个变量。

预期输出如下图所示

为了获得所需的输出,我尝试了如下所示的代码

library(data.table)
df1=as.data.table(df1)
a <- do.call(rbind,
    apply(df1,1,function(i){
     df1[df1[,.I[(X0)==min(X0)],by=ID]$V1]
    })
)

上面的代码有问题。 我正在寻找代码以获得所需的输出

【问题讨论】:

  • 您的代码到底有什么问题?
  • @akrun d 变量只不过是每列相对于行的最小值
  • 我没听懂你最后的评论

标签: r dataframe data-manipulation


【解决方案1】:

我们可以使用map 循环遍历按“ID”分组的“X0”、“V2”列,为该循环列分割值为min 的行,将它们绑定在一起(_dfr ) 并使用这些列中的pmin 创建“d”列

library(dplyr)
library(purrr)
nm1 <- names(df1)[5:6]
map_dfr(nm1, ~ df1 %>%
         group_by(ID) %>%
         slice_min(!! rlang::sym(.x))) %>% 
     ungroup %>%
     mutate(d = select(., all_of(nm1)) %>% reduce(pmin))

-输出

# A tibble: 4 x 7
#      X     Y ID       TI    X0    V2     d
#  <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl>
#1  8.47  48.0 B_1    191. 0.134 0.348 0.134
#2  7.59  48.7 B_1_2 1350. 0.361 0.771 0.361
#3  8.15  48.4 B_1    191. 0.846 0.141 0.141
#4  8.06  48.2 B_1_2 1350. 0.983 0.224 0.224
 

【讨论】:

  • 在样本数据中,我们只有 2 个变量....但在数据集中,我们有 20 多个变量。在这种情况下,为每个变量提及“which.min(V2)”是很费力的。
  • 此外,只需要该特定列的最小值。例如,在 'X0' 列中,0.172 是 ID 'B_1' 的最小值,因此只有第一行 0.172 的 1:4 列将被子集化,列 V2、V3、V4 中的其他值,和 V5 不是必需的。同样,对于 ID 'B_1' 的 V2 列,0.141 是最小值,因此,第 3 行的 1:4 列和第 V2 列的最小值 (0.141) 将被子集化,X0、V3、V4 中的其他值, 和 V5 不是必需的
  • @Kumar 我的理解是你想要'V2'是minX0min的整行。否则,它将只有两行输出,因为只有两个唯一 ID
  • 想要的输出在图中清楚的显示出来了。在图中,我只显示了 X0 和 V2 列。我想要从第 1 列到第 4 列的整行以及它们在 X0、V2、V3、V4 和 V5 列中的最小值
  • 感谢代码和更新.....代码正在运行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-15
  • 1970-01-01
  • 2021-12-13
相关资源
最近更新 更多