【问题标题】:how to subset a list based on ascending/descending order of a column vector in R如何根据R中列向量的升序/降序对列表进行子集化
【发布时间】:2019-10-21 06:31:29
【问题描述】:

如何根据R中满足升序条件的列向量对列表进行子集化?

我有一个包含 30 个对象的列表,其中每个对象有 4 列。我想通过检查每个对象中的第三列是升序还是降序来对列表进行子集化/拆分。如果第 2、4、11、16、19、21 等对象的第 3 列向量按升序排列,则对列表进行子集化。

我的样本数据如下所示

A <- c(477.119,469.483,42.1,453.912,447.7579,41.6,435.2942,429.2672,42.9352)
B <- c(106.98, 106.7397,10.748,106.563,106.646,106.9,106.812,106.98,17.08)
C <- c(10.804,11.108,11.402,11.780,12.033,12.302,12.59634,12.88163,13.19987)
D <- c(10.28718,10.65794,11.02,11.42,11.773,12.11,12.473,12.82436,13.19136)

a1 <- data.frame(A, B, C, D)

A1 <- c(195.5,16.4776,19.408,198.3052,19.2327,20.2429,21.2545,20.3428)
B1 <- c(114.155,114.197,114.239,114.28,114.322,114.364,114.405,114.447)
C1 <- c(41.85957,41.623,41.410,41.205,40.99,40.766,40.540,40.29467)
D1 <- c(31.42653,31.27387,31.129,30.981,30.844,30.6982,30.53915,30.38037)

b1 <- data.frame(A1, B1, C1, D1)

A2 <- c(150.42,11.66,12.95,14.31,15.79,17.531,19.226,11.1279)
B2 <- c(11.724,1.766,11.808,11.849,11.891,11.933,11.975,12.016)
C2 <- c(56.226,55.007,54.0772,53.3295,52.7034,52.1328,51.696,51.3063)
D2 <- c(41.409,40.113,39.228,38.4687,37.83086,37.24863,36.801,36.401)

c1 <- data.frame(A2, B2, C2, D2)
mydata <- list(a1, b1, c1)

从上面提供的数据中,对象[[a1]]的第C列向量是升序的,而其他两个对象是降序的。所以我正在寻找一个代码来检查每个对象的 Cth 列向量的条件并拆分列表。为此,我尝试使用以下代码但无法正常工作。

注意:Cth/3rd 列向量中,当为大向量时,极少数值不按顺序排列

首先我尝试检查列表中的第一个对象

is.ordered(mydata$a1[3])

我得到的结果是:

False

同样的结果也会出现在其他物体上......这是不正确的

for (i in seq_along(mydata)){
    if (is.ordered(i[3]) <- TRUE) {
      mydata1 <- mydata[i]
    else
      mydata2 <- mydata[i]
  }
}

这不行

预期结果如下

mydata1
[[a1]]
A           B               C               D
477.1149    106.6898314 10.80482    10.28718
469.4843    106.7315397 11.10778    10.65794
42.1        10.773248   11.40281    11.02817
453.9212    106.8149563 11.78007    11.42233
447.7579    106.8566646 12.03301    11.773
41.6        106.8983729 12.30212    12.11687
435.2942    106.9400812 12.59634    12.47315
429.2672    106.9817895 12.88163    12.82436
42.9352      17.0234978 13.19987    13.19136

mydata2
[[b1]]
A           B               C               D
195.5   114.1556171 41.85957    31.42653
16.4776 11.1973254  41.62823    31.27387
19.408  11.2390337  41.41062    31.12951
198.30  14.280742   41.20588    30.98881
19.2327 11.3224503  40.9934     30.84694
20.2429 11.3641586  40.76652    30.69182
21.2545 4.4058669   40.54016    30.53915
20.3428 114.4475752 40.29467    30.38037
203.48  114.4892835 40.04356    30.21333

[[c1]]
A           B             C             D
150.42  11.7248034  56.22614    41.40349
11.6695 1.7665117   55.00748    40.16213
12.9522 11.80822    54.07732    39.22808
14.3145 14.8499283  53.32955    38.4687
15.7921 11.8916366  52.70304    37.83086
17.5311 11.9333449  52.13248    37.24863
19.226  11.9750532  51.69696    36.80191
11.1279 12.0167615  51.30663    36.40155
12.3976 12.0584698  51.07735    36.19506

【问题讨论】:

  • 请使用dput以可重现的格式包含样本数据。
  • @MauritsEvers 我以可重复的格式呈现了数据....

标签: r


【解决方案1】:

也许这就是你想要的(或者不是?)

idx <- c()
for (k in seq_along(mydata)){
  if (!is.unsorted(mydata[[k]]$C)) idx <- c(idx, k)
}
mydata.ascending <- mydata[idx]
mydata.descending <- mydata[-idx]

使用!is.unsorted判断列是否升序

【讨论】:

  • @ThomaslsCoding 在指定列号时发布的答案不起作用.....即,我想使用列号而不是列名????提前致谢
  • @Kumar 尝试将!is.unsorted(mydata[[k]]$C 替换为!is.unsorted(mydata[[k]][,colnum],其中colnum 可以指定
【解决方案2】:

this answer 的基础上,您可以使用alldiff 检查数据框元素中的列C 是否按升序排列。 sapply 用于迭代列表中的每个数据帧,并在 C 处于升序时返回一个布尔向量 TRUE

mydata <- list(
  a = data.frame(A = rnorm(10), B = runif(10), C = rev(1:10)),
  b = data.frame(A = rnorm(10), B = runif(10), C = 1:10),
  c = data.frame(A = rnorm(10), B = runif(10), C = sample(1:10, 10)),
  d = data.frame(A = rnorm(10), B = runif(10), C = 1:10)
)

mydata[sapply(mydata, function(x) all(diff(x$C) >= 0))]
#> $b
#>             A          B  C
#> 1  -0.1266213 0.39444137  1
#> 2  -0.2983481 0.69384799  2
#> 3  -1.0826327 0.51337491  3
#> 4   0.1082822 0.62529737  4
#> 5   0.4650216 0.20580597  5
#> 6   0.4129133 0.10899147  6
#> 7   1.6014768 0.88541775  7
#> 8   0.7889176 0.99494885  8
#> 9   0.2097572 0.68434466  9
#> 10 -2.2161454 0.03854874 10
#> 
#> $d
#>             A         B  C
#> 1  -0.1674129 0.1282160  1
#> 2   1.6887421 0.6871053  2
#> 3  -1.2915220 0.5023277  3
#> 4   0.6181605 0.8020529  4
#> 5  -1.0125448 0.4254577  5
#> 6   0.6019005 0.2033730  6
#> 7  -0.6954242 0.3959902  7
#> 8  -2.0667610 0.8642022  8
#> 9  -1.4052872 0.1155380  9
#> 10  1.3859010 0.5984434 10

reprex package (v0.3.0) 于 2019 年 10 月 21 日创建

【讨论】:

  • 发布的答案在用于根据数据框列表中的特定列删除重复行时不起作用.....我使用以下代码删除重复行:mydata1 [.data.frame(x, , unique(x$Time)) 中的错误: 未定义的列选择“
  • 使用下面的代码,它工作了 ...mydata1
  • 如何在贴出的代码中指定列号? “mydata[sapply(mydata, function(x) all(diff(x$C) >= 0))]”... 我想使用列号而不是名称???提前致谢
  • 好的,我明白,但删​​除重复的行不是您最初问题的一部分。很高兴您找到了适合您的解决方案。
猜你喜欢
  • 2023-03-19
  • 2017-12-13
  • 2015-07-30
  • 1970-01-01
  • 2019-11-16
  • 1970-01-01
  • 1970-01-01
  • 2020-04-01
  • 2018-05-03
相关资源
最近更新 更多