创建一个新变量

时间:2014-10-01 13:03:24

标签: r rstudio

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

bankname    bankid  year    totass  invloc1 invamt1 invloc2 invamt2 invloc3 invamt3   
Bank A  1   1881    244789  Philadelphia    7250.32 New York    20218.20    Philadelphia    29513.4   
Bank B  2   1881    195755  Pittsburgh  10243.60    NA  1851.51 NA  NA   
Bank C  3   1881    107736  New York    13357.80    Wilkes-Barre    17761.20    NA  NA   
Bank D  4   1881    170600  Philadelphia    3.35    Philadelphia    2.00    NA  NA   
Bank E  5   1881    32000000    New York    351266.00   New York    314012.00       NA   

但我想使用每个bank的invloc和invamt变量创建一个名为NY_tot的新变量。对于每家银行,如果他们的invloc是纽约,那么总和invamt。 invloc1和invamt1在一起。因此,我希望这个数据集看起来像这样。

bankname    bankid  year    totass  invloc1 invamt1 invloc2 invamt2 invloc3 invamt3 NY_tot   
Bank A  1   1881    244789  Philadelphia    7250.32 New York    20218.20    Philadelphia    29513.4 20218.20   
Bank B  2   1881    195755  Pittsburgh  10243.60    NA  1851.51 NA  NA  0   
Bank C  3   1881    107736  New York    13357.80    Wilkes-Barre    17761.20    NA  NA  13357.80   
Bank D  4   1881    170600  Philadelphia    3.35    Philadelphia    2.00    NA  NA  0   
Bank E  5   1881    32000000    New York    351266.00   New York    314012.00       NA  665278   

这是我正在使用的数据集

bankname <- c("Bank A","Bank B","Bank C","Bank D","Bank E")
bankid <- c( 1, 2,  3,  4,  5)
year<- c( 1881, 1881,   1881,   1881,   1881)
totass  <- c(244789,    195755, 107736, 170600, 32000000)
invloc1 <-c("Philadelphia","Pittsburgh","New York","Philadelphia","New York")
invamt1<-c(7250.32,10243.6,13357.8,3.35,351266)
invloc2<-c("New York","NA","Wilkes-Barre","Philadelphia","New York")
invamt2<-c(20218.2,1851.51,17761.2,2,314012)
invloc3<-c("Philadelphia","NA","NA","NA","")
invamt3<-c(29513.4,NA,NA,NA,NA)
bankdata<-data.frame(bankname, bankid,year,totass, invloc1, invamt1, invloc2, invamt2, invloc3, invamt3)

当我尝试以下代码时:

将因子变量(invloc)更改为字符

i <- sapply(bankdata, is.factor)
bankdata[i] <- lapply(bankdata[i], as.character)  

然后创建一个新变量

for(i in 1:nrow(bankdata)){
 bankdata$NY_tot<-0
for(j in 1:3){
if((!is.na(bankdata[i,paste("invloc",j,sep="")])) && (bankdata[i,paste("invloc",j,sep="")]=="New York")){
  if (!is.na(bankdata[i,paste("invamt",j,sep="")])){
    bankdata$NY_tot[i]<-bankdata$NY_tot[i]+bankdata[i,paste("invamt",j,sep="")]
      }
    }
  }
}

我的NY_tot变量中有0。你能告诉我为什么吗?

提前谢谢!

1 个答案:

答案 0 :(得分:1)

正如其他人在评论中所说,你不需要乱用for循环来做到这一点。 R有许多花哨的内置函数可以快速处理这类问题。

在这种情况下,您的解决方案是ifelse。我对你想要使用哪些列感到困惑,但尝试这样的事情:

bankdata$NY_tot=ifelse(bankdata$invloc1=="New York",sum(bankdata$invamt1,bankdata$invamt2),NA)

这里发生了什么? ifelse的作用如下:

ifelse(conition, value_if_true, value_if_false)

因此,在您的情况下,函数会检查invloc1的值是否为"New York",如果是,则返回一个总和,如果不是,则返回NA。最好的部分是它会逐行自动执行此操作,因此您不需要手动迭代数据框,这就是导致上述代码出现问题的原因。

编辑:根据@Richard Scriven的建议,您可以避免使用withwithin四次输入数据框的名称,例如:

bankdata<-within(bankdata, NY_tot=ifelse(invloc1=="New York"),sum(invamt1,invamt2),NA)

这是我将在余生中使用的一个极好的技巧,它基本上告诉R所有给出的变量名都与bankdata相关联,所以你不必一直输入它。