简体   繁体   English

ifelse在R的数据框中不起作用

[英]ifelse didn't work in dataframe in R

I have a question about ifelse in data.frame in R . 我对R ifelse中的data.frame有疑问。 I checked several SO posts about it, and unfortunately none of these solutions fitted my case. 我检查了几个SO帖子,不幸的是,这些解决方案都不适合我的情况。

My case is, making a conditional calculation in a data frame, but it returns the condition has length > 1 and only the first element will be used even after I used ifelse function in R , which should work perfectly according to the SO posts I checked. 我的情况是,在数据帧中进行条件计算,但返回the condition has length > 1 and only the first element will be used即使在R使用ifelse函数后the condition has length > 1 and only the first element will be used ,根据我检查的SO帖子,它应该可以完美地工作。

Here is my sample code: 这是我的示例代码:

library(scales)
head(temp[, 2:3])
  previous current
1        0      10
2       50      57
3       92     177
4       84     153
5       30      68
6      162     341
temp$change = ifelse(temp$previous > 0, rate(temp$previous, temp$current), temp$current)
rate = function(yest, tod){
  value = tod/yest
  if(value>1){
    return(paste("+", percent(value-1), sep = ""))
  }
  else{
    return(paste("-", percent(1-value), sep = ""))
  }
}

So if I run the ifelse one, I will get following result: 因此,如果我运行ifelse ,将得到以下结果:

head(temp[, 2:4])
  previous current change
1        0      10     10
2       50      57  +NaN%
3       92     177  +NaN%
4       84     153  +NaN%
5       30      68  +NaN%
6      162     341  +NaN%

So my question is, how should I deal with it? 所以我的问题是,我应该如何处理? I tried to assign 0 to the last column before I run ifelse , but it still failed. 在运行ifelse之前,我尝试将0分配给最后一列,但仍然失败。

Many thanks in advance! 提前谢谢了!

Here's another way to do the same 这是另一种方法

# 1: load dplyr
#if needed install.packages("dplyr")
library(dplyr)

# 2: I recreate your data
your_dataframe = as_tibble(cbind(c(0,50,92,84,30,162),
                                 c(10,57,177,153,68,341))) %>% 
  rename(previous = V1, current = V2)

# 3: obtain the change using your conditions
your_dataframe %>% 
  mutate(change = ifelse(previous > 0,
                         ifelse(current/previous > 1,
                                paste0("+%", (current/previous-1)*100),
                                paste0("-%", (current/previous-1)*100)), 
                         current))

Result: 结果:

# A tibble: 6 x 3
  previous current             change
     <dbl>   <dbl>              <chr>
1        0      10                 10
2       50      57               +%14
3       92     177 +%92.3913043478261
4       84     153 +%82.1428571428571
5       30      68 +%126.666666666667
6      162     341 +%110.493827160494

Try the following two segments, both should does what you wanted. 尝试以下两个部分,两者都应该做您想要的。 May be it is the second one you are looking for. 可能这是您要查找的第二个。

library(scales)
set.seed(1)
temp <- data.frame(previous = rnorm(5), current = rnorm(5))
rate <- function(i) {
  yest <- temp$previous[i] 
  tod <- temp$current[i]
  if (yest <= 0)
    return(tod)
  value = tod/yest
 if (value>1) {
   return(paste("+", percent(value-1), sep = ""))
 } else {
   return(paste("-", percent(1-value), sep = ""))
 }
}

temp$change <- unlist(lapply(1:dim(temp)[1], rate))

Second: 第二:

ind <- which(temp$previous > 0)
temp$change <- temp$current
temp$change[ind] <- unlist(lapply(ind, 
                      function(i)  rate(temp$previous[i], temp$current[i])))

In the second segment, the function rate is same as you've coded it. 在第二段中,功能rate与您编写的相同。

Only the first element in value is evaluated. 仅评估value的第一个元素。 So, the output of rate solely depend on the first row of temp . 因此, rate的输出仅取决于temp的第一行。

Adopting the advice I received from warm-hearted SO users, I vectorized some of my functions and it worked! 采纳了我从热情的SO用户那里得到的建议,我对我的一些功能进行了矢量化,并且成功了! Raise a glass to SO community! 向SO社区举杯!

Here is the solution: 解决方法如下:

temp$rate = ifelse(temp$previous > 0, ifelse(temp$current/temp$previous > 1, 
                                             temp$current/temp$previous - 1, 
                                             1 - temp$current/temp$previous), 
                   temp$current)

This will return rate with scientific notation. 这将以科学计数法返回rate If "regular" notation is needed, here is an update: 如果需要“常规”符号,请进行以下更新:

temp$rate = format(temp$rate, scientific = F)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM