【问题标题】:Rename a dataframe Column with text from within the column itself使用列本身中的文本重命名数据框列
【发布时间】:2019-10-19 21:41:10
【问题描述】:

给定一个(简化的)具有格式的数据框

df <- data.frame(a = c(1,2,3,4), 
                 b = c(4,3,2,1), 
                 temp1 = c("-","-","-","foo: 3"), 
                 temp2 = c("-","bar: 10","-","bar: 4")
                 )

a  b   temp1    temp2
1  4     -        -
2  3     -     bar: 10
3  2     -        -
4  1  foo: 3   bar: 4

我需要用列中包含的名称重命名所有临时列,我的最终目标是这样结束:

a  b    foo      bar
1  4     -        -
2  3     -        10
3  2     -        -
4  1     3        4

df 列名和其中包含的数据将是未知的,但是需要更改的列将包含 temp 并且分隔符将始终是“:”

因此,我可以使用 dplyr 从列中轻松删除名称,如下所示:

df <- df %>% 
  mutate_at(vars(contains("temp")), ~(substr(., str_locate(., ":")+1,str_length(.))))

但首先我需要根据某种函数方法重命名列,该方法扫描列并返回其中的值,即。

rename_at(vars(contains("temp")), ~(...some function.....)) 

根据给出的示例,不能保证特定行会有数据,所以我不能简单地从第 1 行获取值

欢迎任何想法。 提前致谢

【问题讨论】:

  • 您希望生成的foo/bar 列是数字列还是保留为字符列?
  • 你的数据是如何获得这种格式的?
  • 数据被抓取,最初有 1 个名为 notes 的列,其中包含多个(重复)条目(即 foo:x、foo:y、bar、z 等)。实际上,我使用 Yannis 在此处提供的方法将可能的类别分为各自的临时列:stackoverflow.com/questions/4350440/…>。这是将数据整理成可用格式的下一步也是最后一步。
  • 我想要数字,但我想这并不重要,因为我可以自己轻松应用这些更改。谢谢。

标签: r dataframe dplyr


【解决方案1】:

涉及dplyrtidyr 的一种可能性可能是:

df %>%
 pivot_longer(names_to = "variables", values_to = "values", -c(a:b)) %>%
 mutate(values = replace(values, values == "-", NA_character_)) %>%
 separate(values, into = c("variables2", "values"), sep = ": ") %>%
 group_by(variables) %>%
 fill(variables2, .direction = "downup") %>%
 ungroup() %>%
 select(-variables) %>%
 pivot_wider(names_from = "variables2", values_from = "values")

      a     b foo   bar  
  <dbl> <dbl> <chr> <chr>
1     1     4 <NA>  <NA> 
2     2     3 <NA>  10   
3     3     2 <NA>  <NA> 
4     4     1 3     4   

如果您想进一步将 NA 替换为 -

df %>%
 pivot_longer(names_to = "variables", values_to = "values", -c(a:b)) %>%
 mutate(values = replace(values, values == "-", NA_character_)) %>%
 separate(values, into = c("variables2", "values"), sep = ": ") %>%
 group_by(variables) %>%
 fill(variables2, .direction = "downup") %>%
 ungroup() %>%
 select(-variables) %>%
 pivot_wider(names_from = "variables2", values_from = "values") %>%
 mutate_at(vars(-a, -b), ~ replace_na(., "-"))

      a     b foo   bar  
  <dbl> <dbl> <chr> <chr>
1     1     4 -     -    
2     2     3 -     10   
3     3     2 -     -    
4     4     1 3     4   

【讨论】:

    【解决方案2】:

    这样就可以了:

    colnames(df)[which(grepl("temp", colnames(df)))] <- unique(unlist(sapply(df[,grepl("temp", colnames(df))],
    
                                                                function(x){gsub("[:].*",
    
                                                                                 "",
    
                                                                                 grep("\\w+",
    
                                                                                      x,
    
                                                                                      value = TRUE))})))
    

    【讨论】:

      猜你喜欢
      • 2018-01-04
      • 2019-09-05
      • 1970-01-01
      • 2017-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      相关资源
      最近更新 更多