【问题标题】:Extract characters and rename columns in R在R中提取字符并重命名列
【发布时间】:2017-03-07 17:05:32
【问题描述】:

我是 R 新手。我从数据库中导出数据并尝试重命名列。

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

例如:

  1. “水.温度.水.温度.BUBU”| “Water.Temp.Temperature.BUBU”
  2. “Water.Temp.Field.Visits.KNF_DUP”
  3. “Sp.Cond.TempCorrected_nodrift.LOD_DUP”
  4. “Sp.Cond.TempCorrected.PFM”
  5. “Sp.Cond.Field.Visits.CC7”
  6. “Cond.Conductivity.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
} 

【问题讨论】:

  • 请考虑参考this discussion 并使您的帖子可复制。我认为您正在寻找 %in%,例如:c("a", "b") %in% c("a", 45)。您的代码似乎在语法上不正确,contains 提供的类似对象将引用对象contains,还有其他奇怪的事情,如果AQexport1 是一个向量,AQexport1,AQexport1[i] 是什么是有意义的,但是我有点想,在您的代码AQexport1 的上下文中对应于一些数据?
  • 在重命名列的情况下,您可以:names(mtcars)[names(mtcars) %in% c("mpg", "cyl")] &lt;- c("renameThisColumn")
  • 感谢康拉德提供的链接。我肯定会在以后的帖子中提到这一点。我知道 colnames 生成了一个可以索引的向量,但正如您所指出的,我错误地认为我可以替换该向量中的值来更改我的数据框中的列名。
  • 您的重命名解决方案有效。但是,由于要更改 240 个唯一的列名,并且列名可能会根据我从数据库中导出的内容而改变,我希望有一个不需要输入每个名称的解决方案。如果我使用 substring() 函数创建新名称,Ryan 的解决方案应该可以工作。

标签: r if-statement for-loop extract columnname


【解决方案1】:

作为一个简化的例子,这就是您如何根据名称是否包含字母“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"

【讨论】:

  • 谢谢,很有帮助!我忘记了逻辑可以转换为 1 或 0。而且,我将使用 substring() 来生成正确的新名称。
【解决方案2】:

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]
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 2013-05-14
    • 2019-08-22
    • 1970-01-01
    • 2015-12-02
    • 2023-02-02
    • 1970-01-01
    相关资源
    最近更新 更多