在嵌套的IF ELSE For循环中取整

时间:2018-11-30 09:57:23

标签: r

是否有一种更干净的方法来比较我的数据框的第三列,并相应地将其除以1000、100或10?我的代码有效,但是有更好的方法编写吗?

除后,我想将其分配给“ Round to 1000”,以此类推。

df <- data.frame(y = c(1,2,3), y1 = c(2,3,4), y2 = c(1000, 100, 10))

    df$Type <- 0
    for (i in 1:nrow(df)){
      if (df[i,3] %% 1000 == 0 ){
        df[i,4] <- "Round to 1000"
      } else if (df[i,3] %% 100 == 0){
        df[i,4] <- "Round to 100"
      } else if (df[i,3] %% 10 == 0){
        df[i,4] <- "Round to 10"
      } else {
        df[i,4] <- "None"
      }
    }

3 个答案:

答案 0 :(得分:3)

根据我的经验,大多数嵌套的if-else语句可以替换为switch()dplyr::case_when()

library(dplyr)

df <- data.frame(
  y = c(1, 2, 3, 5),
  y1 = c(2, 3, 4, 5),
  y2 = c(1000, 100, 10, 5)
)

df %>% 
  mutate(Type = case_when(
    y2 %% 1000 == 0 ~ "Round to 1000",
    y2 %% 100 == 0 ~ "Round to 100",
    y2 %% 10 == 0 ~ "Round to 10",
    TRUE ~ "NONE"
  ))
#>   y y1   y2          Type
#> 1 1  2 1000 Round to 1000
#> 2 2  3  100  Round to 100
#> 3 3  4   10   Round to 10
#> 4 5  5    5          NONE

我认为case_when()可以用一种清晰易读的方式写...

答案 1 :(得分:2)

在这些情况下,我通常会去sapply。它之所以有用,是因为它输出可以插入到data.frame中的原子向量。

df$type <- sapply(df$y2, function(x) {
  if (x %% 1000 == 0 ){
    out <- "Round to 1000"
  } else if (x %% 100 == 0){
    out <- "Round to 100"
  } else if (x %% 10 == 0){
    out <- "Round to 10"
  } else {
    out <- "None"
  }
  out
})

输出

df
#  y y1   y2          type
#1 1  2 1000 Round to 1000
#2 2  3  100  Round to 100
#3 3  4   10   Round to 10

谈论最佳方法,下面是使用标准子集的一种选择。

df$type <- 'None'
for (i in c(10, 100, 1000)) {
  df$type[df$y2 %% i == 0] <- paste('Round to', i)
}

答案 2 :(得分:0)

或者:

/\+91[0-9]{10}/