2017-03-07 276 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