R - Haven - SPSS (.sav):遍历所有列并替换列的名称和标签

问题描述

对于一个项目,我需要将 Excel 和 SPSS 文件与 R 合并。
不确定这是否是我最好的主意。我完成了合并,但是在此过程中 我必须使用 attribute(col)$label 作为名称才能工作。

因此,我最终合并的 data.frame 具有长列名称包括特殊字符(例如 :)。 以下是当前合并的 df 的列名的前几个示例

colnames(combined_retro)
  [1] "Zeitpunkt zu dem das Interview begonnen hat (Europe/Berlin)"                                                             
  [2] "Studiencode: [01]"                                                                                                       
  [3] "Format"                                                                                                                  
  [4] "Geschlecht"                                                                                                              
  [5] "Alter (direkt): Ich bin   ... Jahre"                                                                                     
  [6] "Staatsangehörigkeit"   

所以我创建了另一个 data.frame Naming_Back,其中有两列:Name Label

Naming_Back
   Name     Label 
 1 CASE     Interview-Nummer (fortlaufend)                            
 2 SERIAL   Seriennummer (sofern verwendet)                           
 3 REF      Referenz (sofern im Link angegeben)                       
 4 QUESTNNR Fragebogen,der im Interview verwendet wurde              
 5 MODE     Interview-Modus  

所以现在我想遍历我合并的 data.frame combined_retro 的列 并检查列的当前名称(例如“Zeitpunkt zu dem das Interview begonnen hat (Europe/Berlin)”在第二个 (Naming_Back) 数据框架的标签列中是否可用。 如果是,我想将当前列名与 Name 列提供的列名交换。

我目前的方法是以下循环:

for(i in 1:ncol(retro)) {       # for-loop over columns
  new_name_buffer <- Naming_Back %>% 
    filter(Label == colnames(retro[,i])) 
  if(!(is_empty(new_name_buffer$Name))){
    colnames(retro[,i]) <- new_name_buffer$Name
    print(colnames(retro[,i]))
    print(new_name_buffer$Name)
  }
}

来自循环的打印命令示例

[1] "Geschlecht"
[1] "SD02"
[1] "Staatsangehörigkeit"
[1] "SD04"
[1] "Staatsangehörigkeit: Anders"
[1] "SD04_04"

很明显,问题在于这一行 colnames(retro[,i]) <- new_name_buffer$Name,因为它不会更改列名。有没有人知道如何修复它?

编辑:找到了一个解决方案,通过创建一个字符向量并逐步用缩写名称(如果可用)或旧名称(如果不可用)填充它

new_col_names <- c()
for(i in 1:ncol(retro)) {       # for-loop over columns
  new_name_buffer <- Naming_Back %>% 
    filter(Label == colnames(retro[,i]) <- new_name_buffer$Name
    new_col_names <- c(new_col_names,new_name_buffer$Name)
  }
  else{
    new_col_names <- c(new_col_names,colnames(retro[,i]))
  }
}
colnames(retro) <- new_col_names

EDIT 2: 刚刚找到了一种替代解决方案来覆盖列名,同时使用 for 循环遍历列,您只需执行 names(dataframe)[index],然后使用<- "newColName"

  for(i in 1:ncol(retro)) {       # for-loop over columns
  new_name_buffer <- Naming_Back %>% 
    filter(Label == colnames(retro[,i])) 
  if(!(is_empty(new_name_buffer$Name))){
    names(retro)[i] <- new_name_buffer$Name
    print(colnames(retro[,i]))
    print(new_name_buffer$Name)
  }
}

解决方法

原始代码的问题(如@IRTFM 在对 OP 的评论中正确识别的那样)是,新列名的分配:colnames(retro[,i]) <- new_name_buffer$Name 无法正常工作,因为 colnames 不起作用一个原子向量。

我找到了一种解决方法来覆盖列 name,同时使用 for 循环遍历 data.frame 的列。一个人可以调用 names(dataframe)[index],然后在我的示例中使用 <- "newColName" 分配一个新的列名,因此重要的行看起来像这样:

分配新的列名

names(retro)[i] <- new_name_buffer$Name

for 循环的完整解决方案

for(i in 1:ncol(retro)) {       # for-loop over columns
      # Check if a row with the label is available in the Naming_Back dataframe
      new_name_buffer <- Naming_Back %>% 
         filter(Label == colnames(retro[,I])) 

  # When a Name matching the label is found,replace the old name 
  if(!(is_empty(new_name_buffer$Name))){
    names(retro)[i] <- new_name_buffer$Name
  }
}