您好我有一个看起来像这样的数据集
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。你能告诉我为什么吗?
提前谢谢!
答案 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的建议,您可以避免使用with
或within
四次输入数据框的名称,例如:
bankdata<-within(bankdata, NY_tot=ifelse(invloc1=="New York"),sum(invamt1,invamt2),NA)
这是我将在余生中使用的一个极好的技巧,它基本上告诉R所有给出的变量名都与bankdata
相关联,所以你不必一直输入它。