R 循环的嵌套IF-ELSE中的舍入

R 循环的嵌套IF-ELSE中的舍入,r,R,有没有更干净的方法来比较我的数据帧的第3列,并将其相应地除以1000、100或10?我的代码可以工作,但是有更好的方法来编写它吗 分割之后,我想将其分配给“舍入到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 ){

有没有更干净的方法来比较我的数据帧的第3列,并将其相应地除以1000、100或10?我的代码可以工作,但是有更好的方法来编写它吗

分割之后,我想将其分配给“舍入到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"
      }
    }

df在这些情况下,我通常会选择
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$type <- 'None'
for (i in c(10, 100, 1000)) {
  df$type[df$y2 %% i == 0] <- paste('Round to', i)
}

df$type在这些情况下,我通常选择
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$type <- 'None'
for (i in c(10, 100, 1000)) {
  df$type[df$y2 %% i == 0] <- paste('Round to', i)
}

df$type根据我的经验,大多数嵌套的if-else语句都可以用
switch()
dplyr::case\u-when()替换

库(dplyr)
df%
变异(类型=情况)(
y2%%1000==0~“四舍五入到1000”,
y2%%100==0~“四舍五入到100”,
y2%%10==0~“四舍五入到10”,
对~“无”
))
#>y y1 y2型
#>1.1.2 1000到1000轮
#>2 2 3 100圆对100圆
#>3 3 4 10轮对10轮
#>4 5 5无

在我看来,
case\u-when()
可以以一种干净、可读的方式编写…

根据我的经验,大多数嵌套的if-else语句可以被
switch()
dplyr::case\u-when()
替换:

库(dplyr)
df%
变异(类型=情况)(
y2%%1000==0~“四舍五入到1000”,
y2%%100==0~“四舍五入到100”,
y2%%10==0~“四舍五入到10”,
对~“无”
))
#>y y1 y2型
#>1.1.2 1000到1000轮
#>2 2 3 100圆对100圆
#>3 3 4 10轮对10轮
#>4 5 5无
在我看来,
case\u when()
可以用一种干净、可读的方式编写…

或者:

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

txt <- c("Round to 1000", "Round to 100", "Round to 10", "None")
div <- c(1000, 100, 10, 1)
df$Type <- lapply(df$y2, function(x) {
  txt[which.max(unlist(lapply(div, function(y) (x %% y) == 0)))]
})
#> 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或:


df为什么不简单地
paste('Round to',df$y2)
?在这个特定的例子中,这将是最短和最简单的解决方案,但是,它可能不适合其他更一般的情况。为什么不简单地
paste('Round to',df$y2)
?在这个特定的例子中,这将是最短和最简单的解决方案,它可能不适合其他更一般的情况。@Sotos嵌套
ifelse
s?这是一个选项,但在我看来代码有点不清楚。这就是为什么我选择了
sapply
,它比
for loop
更快、更清晰。现在,你发布的第二种方式更好了!您甚至不能初始化
类型
@Sotos谢谢Soto。当我看到初学者的问题时,我倾向于写尽可能简单的答案。这就是为什么我也选择了
sapply
。矢量化位在这里已经讨论了很多年了:P。对我来说,对于我的数据来说,任何足够快的东西都是很棒的,无论它是否在内部使用for循环。这就是为什么我是data.table的超级粉丝!我完全同意非常感谢你向我展示了实现同一目标的多种方法(:对我来说学习很好!@Sotos Nested
ifelse
s?这是一个选项,但在我看来代码有点不清楚。这就是为什么我选择了
sapply
,它比
for loop
更快更清晰。现在你发布的第二种方式要好得多!你甚至不能初始化
类型,谢谢Soto。我倾向于写答案这就是为什么我也选择了
sapply
。矢量化位在这里已经讨论了很多年了:P。对于我来说,任何足够快的数据都是很棒的,无论它是否在内部使用for循环。这就是为什么我是数据的忠实粉丝。table!我完全同意。:)非常感谢您向我展示了实现同一目的的多种方法(:对我来说学习得很好!函数完美工作时的这种情况!它看起来与SQL中的情况非常相似。非常感谢;从未知道存在这种情况(:函数完美工作时的这种情况!它与SQL中的情况非常相似。非常感谢;从未知道存在这种情况(: