R:有条件地替换循环中的值

时间:2013-07-15 20:40:33

标签: r loops replace conditional-statements

我有一个像这样的数据框:

rel      <- c(2, 5, NA, 3, 6)
year.in  <- c(4, NA, 2, 3, 2)
year.out <- c(6, 7, NA, 5, 4)
year.1   <- c(NA, NA, NA, NA, NA)
year.2   <- c(NA, NA, NA, NA, NA)
year.3   <- c(NA, NA, NA, NA, NA)
year.4   <- c(NA, NA, NA, NA, NA)
year.5   <- c(NA, NA, NA, NA, NA) 

df <- as.data.frame(cbind(rel, year.in, year.out, year.1, year.2, year.3, 
                      year.4, year.5))

我想要做的是更新year.1 - year.5中的缺失值,其值为'rel',但仅限于:(year.in&gt; = year.i AND year.out&lt; = year.i)(我是1:5)

关注刚进入的那一年,我想出了这个:

for (i in 1:5) ifelse(df$year.in < i,
    df[paste("year", i, sep= ".")]<- NA,
    df[paste("year", i, sep= ".")]<- df["rel"])

但这只是将所有year.i变量替换为rel。

的值

我有两个问题:

  • 如何在上述条件下使用'rel'值更新year.i变量?

  • 在这里使用if else语句是不是很糟糕?

最好并提前致谢,

理查德

2 个答案:

答案 0 :(得分:4)

library(data.table)
dt = data.table(df)

for(i in 1:5) dt[year.in <= i & i <= year.out, paste0('year.', i) := rel]

dt
#   rel year.in year.out year.1 year.2 year.3 year.4 year.5
#1:   2       4        6     NA     NA     NA      2      2
#2:   5      NA        7     NA     NA     NA     NA     NA
#3:  NA       2       NA     NA     NA     NA     NA     NA
#4:   3       3        5     NA     NA      3      3      3
#5:   6       2        4     NA      6      6      6     NA

答案 1 :(得分:1)

我使用meltreshape2您的数据:

library(reshape2)    
df.melt <- melt(df, id.vars=c('rel', 'year.in', 'year.out'))

挖出数字年份:

df.melt$year <- as.integer(gsub('year\\.', '', df.melt$variable))

然后使用矢量化操作:

subsetter <- with(df.melt, year.in >= year & year.out <= year.out)
subsetter[is.na(subsetter)] <- FALSE
df.melt$value[subsetter] <- df.melt$rel[subsetter]

然而,在你的例子中,一切都失败了。

使用ifelse是完全可以接受的,但是,不要在内部进行分配。而是将其结果分配给某些内容,如下所示。问题在于,您在ifelse内执行的两项任务不在每个子集上,而是表现为它们只是独立运行。

for (i in 1:5) {
  year_col <- paste('year', i, sep='.')
  df[[year_col]] <- ifelse(df$year.in >= i & df$year.out <= i,
                         df$rel,
                         df[[year_col]])
}

回答你的子弹:

  • 见上文。

  • 使用ifelse没有什么特别的错误,有时这样做是为了便于阅读。但是,它是一个“循环”结构,因此通常可以用更有效的矢量化解决方案代替。