根据R中的多个条件替换数据集中的值

时间:2015-07-27 19:13:48

标签: r

我有一个看起来像这样的数据集:

age  Year  f.pop   f.dc 
1    1990      0      1
5    2001    200      4
1    1990    400      2 
1    2001     50      3
5    2001      0      3

我希望它看起来像这样:

age  Year  f.pop  f.dc 
1    1990    400     1
5    2001    200     4
1    1990    400     2
1    2001     50     3 
5    2001    200     3 

基本上,我想将数据集的f.pop列中的零值替换为与其他两列(年份和年龄)匹配的行的f.pop值。 f.dc列与此问题基本无关,但我想强调这些行不相同,必须保持独立。

这是我的尝试:

for (i in 1:length(usbd$f.pop)) {
  if (usbd$f.pop[i] == 0) {
     iage = usbd$age[i]  
     iyear = usbd$Year[i]
     index = which(usbd$age == iage & usbd$Year == iyear)
     usbd$f.pop[i] = usbd$f.pop[index] }} 

但这非常慢。必须有一种更有效的方式。

Conditional replacement of values in a data.frame很有用,但我不确定如何将其应用于具有可能不同索引的两个条件。

1 个答案:

答案 0 :(得分:2)

我们可以使用data.table来替换' 0'在' f.pop'中的值(假设' f.pop'值对于每个'年龄'年'组来说是唯一的。转换' data.frame'到' data.table' (setDT(df1)),按年龄和年份(.(age, Year))分组,我们指定了f.pop'作为' f.pop'中的非零值(f.pop := f.pop[f.pop!=0])。

library(data.table)
setDT(df1)[, f.pop:= f.pop[f.pop!=0] , by = .(age, Year)]
df1
#   age Year f.pop f.dc
#1:   1 1990   400    1
#2:   5 2001   200    4
#3:   1 1990   400    2
#4:   1 2001    50    3
#5:   5 2001   200    3

数据

df1 <- structure(list(age = c(1L, 5L, 1L, 1L, 5L), Year = c(1990L, 2001L, 
1990L, 2001L, 2001L), f.pop = c(0L, 200L, 400L, 50L, 0L), f.dc = c(1L, 
4L, 2L, 3L, 3L)), .Names = c("age", "Year", "f.pop", "f.dc"), 
class =  "data.frame", row.names = c(NA, -5L))