2017-03-07 273 views
0

我是R新手。我从数据库导出数据,并试图重命名列。在R中提取字符和重命名列

示例现有名称(每个水质参数一个站点)在下面引号。每个站点和40个站点​​有6个可能的参数;我想根据参数和站点重新命名列。网站名称为3-7个字符,始终出现在最后一个小数点后面。我的数据集(AQexport1)有240列和47,714行(行是小时连续数据的时间戳)。我希望能够使用相同格式和参数的数据库中的其他导出代码,但可能会使用不同的站点。

例如:

  1. “Water.Temp.Water.Temp.BUBU” | “Water.Temp.Temperature.BUBU” < --- Temp.BUBU
  2. “Water.Temp.Field.Visits.KNF_DUP” < --- FVTemp.KNF_DUP
  3. “Sp.Cond.TempCorrected_nodrift.LOD_DUP” < --- SpCnd.LOD_Dup
  4. “Sp.Cond.TempCorrected.PFM” < --- SpC.PFM
  5. “Sp.Cond.Field.Visits.CC7” < - FVSpC.CC7
  6. “电导率.Conductivity.TM02Dup“< - Cond.TM02Dup

我无法弄清楚如何在if语句中编写contains()(我意识到下面的语法是错误的,我只是试图展示我在想什么),或者如何从字符串中提取字符多个小数点,并且不会从列名的末尾提取相同数量的字符。我也想知道通过colnames()进行for循环是否是最好的解决方案。

for (i in 1:colnames(AQexport1)){ 
    if (colnames(AQexport1[i]) contains "Water.Temp.W" | "Water.Temp.T"){ 
    colnames(AQexport1[i]) <- Temp.insert_site_name_here 
    } 
    elseif (colnames(AQexport1[i])) contains "Water.Temp.F") { 
     colnames(AQexport1[i]) <- FVTemp.insert_site_name_here 
    } 
    elseif (colnames(AQexport1[i])) contains "nodrift") { 
     colnames(AQexport1[i])<-SpCnd.insert_site_name_here 
    } 
    elseif (colnames((AQexport1[i])) contains "Sp.Cond.T") { 
     colnames(AQexport1[i])<-SpC.insert_site_name_here 
    } 
#continue elseif statements 
} 
+1

请考虑参考[本讨论](http://stackoverflow.com/q/5963269/1655567)并使您的文章可重现。我认为你正在寻找**'%in%'**,例如:%c(“a”,45)'中的'c(“a”,“b”)%。你的代码看起来在语法上不正确,提供的'contains'就是指对象'contains',还有其他奇怪的东西,'AQexport1'是什么,'AQexport1 [i]'如果'AQexport1'是一个矢量,但我认为,在你的代码的上下文中'AQexport1'对应于一些数据? – Konrad

+0

在重命名列的上下文中,您可以:%c(“mpg”,“cyl”)中的名称(mtcars)[名称(mtcars)%] < - c(“renameThisColumn”)' – Konrad

+0

谢谢Konrad链接。我一定会在以后的文章中提到这一点。我知道colnames生成了一个我可以编制索引的向量,但正如您所指出的那样,我错误地认为我可以替换该向量中的值来更改数据框中的列名称。 – Ecologist711

回答

0

AQexport 1是我的数据集,需要新的列名称。这是我的解决方案。

# 6 parameters with 11 syntax's to change column names for (each syntax could have up to 40 variations (.site names): 
# "Water.Temp.Water.Temp.BUBU" or 
# "Water.Temp.Temperature.BUBU" or 
# "Water.Temp.Temp.BUBU"<--- Temp.BUBU 
# "Water.Temp.Field.Visits.KNF_DUP" <--- FVTemp.KNF_DUP 
# "Sp.Cond.Sp.Cond.TempCorrected_nodrift.DRBR" or 
# "Sp.Cond.Sp.Cond..TempCorrected_nodrift.BRCD" or 
# "Sp.Cond.SpCond.nodrift.TM01" or 
# "Sp.Cond.TempCorrected_nodrift.LOD_DUP" <---SpCnd.site 
# "Sp.Cond.TempCorrected.PFM" <--- SpC.PFM 
# "Sp.Cond.Field.Visits.CC7" <-- FVSpC.CC7 
# "Cond.Conductivity.TM02Dup"<-- Cond.TM02Dup 
# nchar("Sp.Cond.TempCorrected_nodrift.DRBR") #number of characters in string 

#logical vectors, TRUE if AQexport1 column names match charcter input in grepl 
Names<-names(AQexport1) 
Temp.siteW<-grepl("Water.Temp.Water.Temp", Names) 
Temp.siteT<-grepl("Water.Temp.Temperature", Names) 
Temp.siteTT<-grepl("Water.Temp.Temp", Names) 
FVTemp.site<-grepl("Temp.Field", Names) 
FVSpC.site<-grepl("Sp.Cond.Field", Names) 
SpCnd.site1<-grepl("Sp.Cond.Sp.Cond.TempCorrected_nodrift.", Names) 
SpCnd.site2<-grepl("Sp.Cond.Sp.Cond..TempCorrected_nodrift..", Names) 
SpCnd.site3<-grepl("Sp.Cond.SpCond.nodrift.", Names) 
SpCnd.site4<-grepl("Sp.Cond.TempCorrected_nodrift.", Names) 
Cond.site<-grepl("Cond.C", Names) 
SpC.site<-grepl("Sp.Cond.TempCorrected.", Names) #Sp.Cond.TempCorrected. the last period is critical to distinguish from nodrift 

#Creating new column name: Paste parameter prefix to site name (extracted from old column name with substring) 
#Making parameter always 4 characters 
Temp.namesW<-paste("Temp.",substring(Names,23), sep="") 
Temp.namesT<-paste("Temp.",substring(Names,24), sep="") 
Temp.namesTT<-paste("Temp.",substring(Names,17), sep="") 
FVTemp.names<-paste("FTem.",substring(Names,25), sep="") 
FVSpC.names<-paste("FSpC.",substring(Names,22), sep="") 
SpCnd.names1<-paste("SCnd.",substring(Names,39), sep="") 
SpCnd.names2<-paste("SCnd.",substring(Names,40), sep="") 
SpCnd.names3<-paste("SCnd.",substring(Names,24), sep="") 
SpCnd.names4<-paste("SCnd.",substring(Names,31), sep="") 
Cond.names<-paste("Cond.",substring(Names,19), sep="") 
SpC.names<-paste("SpCc.",substring(Names,23), sep="") 

for (i in 1:ncol(AQexport1)){ 
    if(Temp.siteW[i]){ 
    names(AQexport1)[i]<-Temp.namesW[i] 
    } 
    else if(Temp.siteT[i]){ 
    names(AQexport1)[i]<-Temp.namesT[i] 
    } 
    else if(Temp.siteTT[i]){ 
    names(AQexport1)[i]<-Temp.namesTT[i] 
    } 
    else if(FVTemp.site[i]){ 
    names(AQexport1)[i]<-FVTemp.names[i] 
    } 
    else if(FVSpC.site[i]){ 
    names(AQexport1)[i]<-FVSpC.names[i] 
    } 
    else if(SpCnd.site1[i]){ 
    names(AQexport1)[i]<-SpCnd.names1[i] 
    } 
    else if(SpCnd.site2[i]){ 
    names(AQexport1)[i]<-SpCnd.names2[i] 
    } 
    else if(SpCnd.site3[i]){ 
    names(AQexport1)[i]<-SpCnd.names3[i] 
    } 
    else if(SpCnd.site4[i]){ 
    names(AQexport1)[i]<-SpCnd.names4[i] 
    } 
    else if(Cond.site[i]){ 
    names(AQexport1)[i]<-Cond.names[i] 
    } 
    else if(SpC.site[i]){ 
    names(AQexport1)[i]<-SpC.names[i] 
    } 
} 
0

作为一个简化的情况下,这是怎么了,你会根据是否含有字母“A”或“B”重新分配的名称,或含有“C”或“d”,等等。

dat <- data.frame(aa = runif(10), ba = runif(10), ct = runif(10), df = runif(10), en = runif(10), zz = runif(10)) 

names(dat) 
## "aa" "ba" "ct" "df" "en" "zz" 

library(magrittr) 

# logical, TRUE if names contain a or b 
condition1 <- sapply(c('a','b'), grepl, names(dat)) %>% rowSums %>% as.logical 

# logical, TRUE if names contain c or d 
condition2 <- sapply(c('c','d'), grepl, names(dat)) %>% rowSums %>% as.logical 

# logical, TRUE if names contain e 
condition3 <- grepl('e', names(dat)) 



names(dat) <- ifelse(condition1, 'newname1', 
       ifelse(condition2, 'newname2', 
       ifelse(condition3, 'newname3', 
           'newname4'))) 

names(dat) 
## [1] "newname1" "newname1" "newname2" "newname2" "newname3" "newname4" 
+0

谢谢,非常有帮助!我忘记逻辑可以转换为1或0。而且,我将使用substring()来创建正确的新名称。 – Ecologist711

+0

我会考虑它的回答(这是一个意外,我没有回答它)。但是,对于我的数据集,对于每种情况,我最多可以有40个不同的名称。所以,这很接近,但不是完整的答案。 (但是,这可能是由于我不清楚的问题)。 – Ecologist711