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

R - Haven - SPSS (.sav): Iterate over all columns and replace name and label of columns

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

我的最终合并 data.frame 因此可以使用包括特殊字符(例如 :)的长列名。 以下是当前合并后的 df 的 colnames 的前几个示例

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) data.frame 的标签列中是否可用。 如果是,我想将当前列名称与 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])) 
  if(!(is_empty(new_name_buffer$Name))){
    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

编辑 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 没有在原子向量上工作。

我找到了在使用 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
  }
}