【问题标题】:How do I speed up this specific for loop?如何加快这个特定的 for 循环?
【发布时间】:2021-09-03 16:01:58
【问题描述】:

我查看了其他线程并尝试将其应用到我的代码中,但没有成功。

CDR3_post_challenge_unique_clonecount$participant_per_cdr3aa <- as.numeric(CDR3_post_challenge_unique_clonecount$cdr3aa)
participant_list <- unique(CDR3_post_challenge_unique_clonecount$cdr3aa)
for (c in participant_list)
{
  CDR3_post_challenge_unique_clonecount$participant_per_cdr3aa[CDR3_post_challenge_unique_clonecount$cdr3aa == c] <- length(unique(CDR3_post_challenge_unique_clonecount$PartID[CDR3_post_challenge_unique_clonecount$cdr3aa == c]))
}

这是数据框的一部分:

cdr3aa              clonecount  PartID
CAAGRAARGGSVPHWFDPF 1           S-1
CAALADSGSQTDAFDIA   1           S-1
CAFHAAYGSQHGLDVW    1           S-1
CAGGLAWLVDDW        1           S-1
CAGRWFFPW           1           S-1
CAGVKNGRGMDVW       1           S-1

【问题讨论】:

  • 嗨!您能否使用dput () 提供您的数据框和参与者列表的样本,因为没有它,很难理解我们正在处理的内容。在此处阅读有关制作可重现示例的更多信息:stackoverflow.com/questions/5963269/…

标签: r for-loop


【解决方案1】:

我认为您可以将 for 循环替换为

CDR3_post_challenge_unique_clonecount$per3 <-
  as.integer(
    ave(CDR3_post_challenge_unique_clonecount$PartID,
        CDR3_post_challenge_unique_clonecount$cdr3aa,
        FUN = function(z) length(unique(z)))
  )

我将通过mtcars 进行演示,使用以下类比:

  • mtcars --> CDR3_post_challenge_unique_clonecount
  • cyl --> cdr3aa,我们要计算的分类变量PartID
  • drat --> PartID,我们想在每个 cdr3aa 中(唯一地)计算的东西
mtcars$drat_per_cyl <- ave(mtcars$drat, mtcars$cyl, FUN = function(z) length(unique(z)))
mtcars
#                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb drat_per_cyl
# Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4            5
# Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4            5
# Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1           10
# Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1            5
# Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2           11
# Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1            5
# Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4           11
# Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2           10
# Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2           10
# Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4            5
# Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4            5
# Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3           11
# Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3           11
# Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3           11
# Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4           11
# Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4           11
# Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4           11
# Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1           10
# Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2           10
# Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1           10
# Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1           10
# Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2           11
# AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2           11
# Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4           11
# Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2           11
# Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1           10
# Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2           10
# Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2           10
# Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4           11
# Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6            5
# Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8           11
# Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2           10

注意事项:

  • ave 是一个脑死亡,因为返回值的类总是与第一个参数的类相同。这意味着不能计算唯一的 "character" 并期望得到一个整数,而是作为字符串返回。正因为如此,我将ave 包裹在as.integer(.) 中。

  • ave 返回一个与输入长度相同的向量,其值对应于 1-for-1(表示顺序相关且保留)。在我的 mtcars 示例中,这意味着它正在有效地执行以下操作:

    ind4 <- which(mtcars$cyl == 4L)
    ind4
    #  [1]  3  8  9 18 19 20 21 26 27 28 32
    length(unique(mtcars$drat[ind4]))
    # [1] 10
    ind6 <- which(mtcars$cyl == 6L)
    ind6
    # [1]  1  2  4  6 10 11 30
    length(unique(mtcars$drat[ind6]))
    # [1] 5
    ### ...
    

    但它会将返回值10 放在返回值的ind4 位置。比如因为我的ind6,返回值会以

    开头
    c(5, 5, .., 5, .., 5, .., .., .., 5, 5, .., .....)
    

    因为ind4,所以会包含

    c(.., .., 10, .., .., .., .., 10, 10, .....)
    

    cyl==8L 也一样。)

【讨论】:

  • 嗨,我已经尝试过了,但最终每行都得到了 NA 的输出。
  • 这很有趣。
  • 我收到此警告:50: In `[&lt;-.factor`(`*tmp*`, i, value = 1L) : invalid factor level, NA generated
  • 好的。虽然我完全理解“我不允许”共享示例数据,但您是否明白如果没有可重现的东西,我能做的很少吗?要么找到一种方法来匿名化您的数据(无需使其可逆,您可能只需要对其进行去标识化)或找到一种方法来生成足够相似(即代表性)的假样本数据我们可以使用。祝你好运。
  • 我在帖子中添加了一个示例
猜你喜欢
  • 1970-01-01
  • 2014-06-29
  • 1970-01-01
  • 2019-07-25
  • 1970-01-01
  • 1970-01-01
  • 2020-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多