我有一个像这样的数据框:
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语句是不是很糟糕?
最好并提前致谢,
理查德
答案 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)
我使用melt
包reshape2
您的数据:
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
没有什么特别的错误,有时这样做是为了便于阅读。但是,它是一个“循环”结构,因此通常可以用更有效的矢量化解决方案代替。