【问题标题】:Nested ifelse statement in a for loop在 for 循环中嵌套 ifelse 语句
【发布时间】:2019-06-05 18:58:39
【问题描述】:

我正在尝试在 for 循环中使用嵌套 ifelse 语句来创建一个新变量,其值基于因子变量(邮政编码列表)的出现频率。

新变量应根据邮政编码的频率(频率范围在 1 到 4 之间)返回一系列预定义的数字。这些数字系列中的每一个都必须以 800 结尾并以 200 为增量增加,其起点取决于每个邮政编码的频率:频率越高,200 的起始增量越低。

为此,我定义了一个 for 循环,在其中我首先测量每个邮政编码的频率,然后是一个嵌套的 ifelse 语句,根据频率指定要分配给 NewVar 的每个数字系列。

这里写了一个我想要实现的小直观示例,我想将其应用于包含数百万邮政编码的数据框。

期望的结果:

Postcode  NewVar
AA        600
AA        800
BB        400
BB        600
BB        800
CC        800
DD        200
DD        400
DD        600
DD        800

代码:

DF$NewVar <- 0

DF$NewVar <- for (i in levels(DF$Postcode[i]))
ifelse((table(DF$Postcode[i]) == 4), DF$NewVar[i] <- c(200,400,600,800),
  (ifelse ((table(DF$Postcode[i]) == 3), DF$NewVar[i] <- c(400,600,800),
    (ifelse ((table(DF$Postcode[i]) == 2), DF$NewVar[i] <- c(600,800), 
      DF$NewVar[i] <- c(800))))))

问题 1:

首先,在运行整个代码时,我收到一条错误消息,指出替换中的行数与数据不匹配,而在手动检查时,情况并非如此(不匹配总是仅限于 1 行)。

Error in `$<-.data.frame`(`*tmp*`, NewVar, value = c("0", "0", "0",  : 
replacement has 11 rows, data has 10.

问题 2:

测试 IFELSE 是否独立工作(在循环之外):

在验证 ifelse 子句是否独立工作时(循环外),我看到在 NewVar 的每一行上只复制了 200 的起始增量,因此它不会增加到 800。这不是我的想要实现:

代码测试一个 IFELSE:

DF$NewVar[1:2] <- ifelse((sum(table(DF$Postcode)) == 2),                       
  DF$NewVar[1:2] <- c(600,800), "NA")

结果(不需要):

Postcode  NewVar
AA        200
AA        200

期望的结果:

Postcode  NewVar
AA        200
AA        400

注意:我在尝试分配变量之前预定义了 NewVar 列,并且我已经检查了 NA。

提前感谢您的宝贵时间。

【问题讨论】:

    标签: r loops for-loop if-statement nested


    【解决方案1】:

    如果您愿意使用 dplyr 的一种方法:

    library(dplyr)
    DF <- structure(list(Postcode = c("AA", "AA", "BB", "BB", "BB", "CC", 
    "DD", "DD", "DD", "DD")), class = "data.frame", row.names = c(NA, 
    -10L))
    
    vals <- c(200,400,600,800)
    DF %>% group_by(Postcode) %>% mutate(NewVar = tail(vals,n()))
    

    【讨论】:

    • 感谢@joran 提供的这个解决方案:事实证明,它比我最初尝试的三重嵌套 ifelse 更加用户友好。另外,(如果我错了,请纠正我)但是在数百万数据上运行此代码时,使用 dplyr 可以为我节省大量时间,而不是 ifelse 迭代。
    【解决方案2】:

    为了完整起见,这里是一个使用ave() 函数的基本 R 解决方案。

    假设Postcode 是一个随机排列的邮政编码的向量

    Postcode
    
     [1] "BB" "CC" "CC" "BB" "BB" "AA" "CC" "BB" "AA" "DD"
    

    下面的代码创建了一个包含PostcodeNewVar的data.frame:

    data.frame(
      Postcode, 
      NewVar = ave(Postcode, Postcode, 
                   FUN = function(x) seq(to = 800, by = 200, length.out = length(x)))
    )
    
       Postcode NewVar
    1        BB    200
    2        CC    400
    3        CC    600
    4        BB    400
    5        BB    600
    6        AA    600
    7        CC    800
    8        BB    800
    9        AA    800
    10       DD    800
    

    数据

    # create data
    library(magrittr)   # only used to improve readability
    n_codes <- 4L
    set.seed(1L)
    Postcode <- 
      stringr::str_dup(LETTERS[1:n_codes], 2L) %>% # create codes
      rep(times = sample(n_codes)) %>%             # replicate randomly
      sample()                                     # re-order randomly
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-11
      • 1970-01-01
      • 1970-01-01
      • 2013-08-03
      • 1970-01-01
      • 1970-01-01
      • 2019-04-22
      相关资源
      最近更新 更多