[英]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.