2017-05-08 191 views
1

我使用一系列if语句来检查Year是否等于某个值,然后计算语句。有没有更高效,更快捷的方法来执行以下内容而不是使用if语句?替代R语句中的if语句

for (i in 1:length(O$Year)) 
{ 
    if (Year[i] == "2012") { 
     O$SD[i] = C[i]/5408666 
    } else if (Year[i] == "2013") { 
     O $SD[i] = C[i]/5300759 
    } else if (Year[i] == "2014") { 
     O$SD[i] = C[i]/5410924 
    } else if (Year[i] == "2015") { 
     O$SD[i] = C[i]/5446029 
    } else if (Year[i] == "2016") { 
     O$SD[i] = C[i]/5480869 
    } else 
     O$SD[i] = C[i] 
} 

**Data set named O** 
    **SD Year C** 
    43 2012 4 
    23 2012 5 
    12 2014 3 
    53 2014 3 
+1

那么[switch](https://stat.ethz.ch/R-manual/R-devel/library/base/html/switch.html)怎么样? – user2100721

回答

0

我很想看看如何与switch()做到这一点,我通常会用dplyr管道,以避免必须如此频繁输入data.frame的名字,但这里是我会在这里做的:

O$SD <- ifelse(O$Year == '2012', O$C/5408666, 
       ifelse(O$Year == '2013', O$C/5300759, 
         ifelse(O$Year == '2014', O$C/5410924, 
          ifelse(O$Year == '2015', O$C/5446029, 
            ifelse(O$YEar == '2016', O$C/5480869, O$C)))) 

它不会节省大量的打字量,但它确实节省了for循环。

+0

您也可以使用'with'来避免重复键入数据框名称。 – Gregor

+0

'switch'为第一个参数取一个值,所以你必须把它包装在'for'循环中。这通常是我会避免的。 – Benjamin

1

这个怎么样?

tmp <- data.frame(year = c("2012","2013","2014","2015","2016"), 
denominator = c(5408666,5300759,5410924,5446029,5480869)) 

for(i in 1:nrow(O)){ 
O[i,4] <- O$C[i]/tmp[which(as.character(tmp$year)==O$Year[i]),2] 
} 
1

可以使用dplyr::recodeswitch工作方式类似:

虚拟数据:

library(dplyr) 

O <- read.table(text="SD Year C 
    43 2012 4 
23 2012 5 
12 2014 3 
53 2014 3", header=TRUE, stringsAsFactors=FALSE) 

重新编码:注意反引号``围绕要被替换的值:

O %>% mutate(SD= recode(Year,`2012`=C/540866, 
          `2014`=C/5410924)) 

结果:

  SD Year C 
1 7.395547e-06 2012 4 
2 9.244434e-06 2012 5 
3 5.544340e-07 2014 3 
4 5.544340e-07 2014 3 
0

我认为如果您使用match将分母分配给每一行,您会发现效率最高。

match_year_row <- match(O$year, 2012:2016) 

O$denominator <- c(5408666,5300759,5410924,5446029,5480869)[match_year_row] 
O$denominator[is.na(O$denominator)] <- 1 
O$SD <- with(O, C/denominator)