【问题标题】:Prefixes in variable names and multiple new data frames in loops in RR中的变量名称中的前缀和循环中的多个新数据帧
【发布时间】:2017-10-03 19:50:49
【问题描述】:

数据框 Day1 和 Day2 均包含带前缀的变量名称(分别为 rad_ 和 tv_,以及 you_ 和 pho_)。每个数据框还包含不带前缀的变量名称,我想为这些变量名称添加前缀 (noncom_)。最后,我想创建新的数据框 NewDay1 和 NewDay2,它们部分以原始数据框命名,但其中所有变量名称都有前缀。实际上有很多数据框,所以我的目标是一个通用的解决方案。任何帮助将非常感激。

起点(dfs):

Day1 <- data.frame("rad_cat"=c(NA,NA,NA),"tv_dog"=c(NA,NA,NA) ,"tv_turkey_E3"=c(NA,NA,NA), "zebra_E2"=c(NA,NA,NA), "elephant"=c(NA,NA,NA))
Day2 <- data.frame("you_cat"=c(NA,NA,NA),"pho_horse_E3_E6"=c(NA,NA,NA) ,"pho_cow_E4_E4_E1"=c(NA,NA,NA), "hippo_E1"=c(NA,NA,NA), "lion_E4_E1"=c(NA,NA,NA))

期望的结果(dfs):

NewDay1 <- data.frame("rad_cat"=c(NA,NA,NA),"tv_dog"=c(NA,NA,NA) ,"tv_turkey_E3"=c(NA,NA,NA), "noncom_zebra_E2"=c(NA,NA,NA), "noncom_elephant"=c(NA,NA,NA))
NewDay2 <- data.frame("you_cat"=c(NA,NA,NA),"pho_horse_E3_E6"=c(NA,NA,NA) ,"pho_cow_E4_E4_E1"=c(NA,NA,NA), "noncom_hippo_E1"=c(NA,NA,NA), "noncom_lion_E4_E1"=c(NA,NA,NA))

目前的尝试:

library(dplyr)
dfs <- list(Day1, Day2)  
numdfs <- length(dfs)
for (i in 1:numdfs) 
{
  dfa <- dfs[i] %>% select(-matches("rad_|tv_")) %>% setNames(paste0('noncom_', names(.)))
  dfb <- dfs[i] %>% select(matches(c("rad_|tv_")))
  dfc <- cbind(dfa,dfb)  ]
  name<-paste("New",dfs[i],sep="")
  assign(name, dfc))
}

【问题讨论】:

  • 还有很多前缀吗?或者你只有这4个? (rad_ 和 tv_,还有 you_ 和 pho_)

标签: r dataframe


【解决方案1】:

这是一种使用 rename_at 的方法,它将函数应用于列名的子集。

vars 参数描述了我们想要更改的列名。在这种情况下,它是除以前缀开头的列之外的每一列。

下一个参数是我们要应用于所选列名的函数。

library('tidyverse')

set_prefixes <- function(df) {
  df %>%
    rename_at(
      vars(
        -starts_with('rad_'),
        -starts_with('tv_'),
        -starts_with('you_'),
        -starts_with('pho_')),
      ~stringr::str_c('noncom_', .x))
}

map(list(Day1, Day2), set_prefixes)
# [[1]]
#   rad_cat tv_dog tv_turkey_E3 noncom_zebra_E2 noncom_elephant
# 1      NA     NA           NA              NA              NA
# 2      NA     NA           NA              NA              NA
# 3      NA     NA           NA              NA              NA
# 
# [[2]]
#   you_cat pho_horse_E3_E6 pho_cow_E4_E4_E1 noncom_hippo_E1 noncom_lion_E4_E1
# 1      NA              NA               NA              NA                NA
# 2      NA              NA               NA              NA                NA
# 3      NA              NA               NA              NA                NA

如果您想使用正则表达式而不是 starts_with,您可以执行以下操作:

set_prefixes <- function(df) {
  df %>%
    rename_at(
      vars(-matches('rad_|tv_|you_|pho_')),
      ~stringr::str_c('noncom_', .x))
}

【讨论】:

    【解决方案2】:

    这是一个函数,rename_fun,用于将前缀添加到没有定义前缀的那些。之后,我们可以使用lapply 将此功能应用于所有数据框。

    library(magrittr)
    
    rename_fun <- function(x, prefix = "noncom_"){
      x2 <- x %>%
        setNames(ifelse(!grepl("rad_|tv_|you_|pho_", names(.)), paste0(prefix, names(.)), names(.)))
      return(x2)
    }
    
    lapply(list(Day1, Day2), rename_fun)
    [[1]]
      rad_cat tv_dog tv_turkey_E3 noncom_zebra_E2 noncom_elephant
    1      NA     NA           NA              NA              NA
    2      NA     NA           NA              NA              NA
    3      NA     NA           NA              NA              NA
    
    [[2]]
      you_cat pho_horse_E3_E6 pho_cow_E4_E4_E1 noncom_hippo_E1 noncom_lion_E4_E1
    1      NA              NA               NA              NA                NA
    2      NA              NA               NA              NA                NA
    3      NA              NA               NA              NA                NA
    

    更新

    lapply 的输出是一个列表。我们可以将输出存储到一个对象中,并使用以下方式访问每个数据帧。

    Day_list <- lapply(list(Day1, Day2), rename_fun)
    
    NewDay1 <- Day_list[[1]]
    NewDay2 <- Day_list[[2]]
    

    【讨论】:

    • 在ycw提供的解决方案中,如何将输出变成单独的数据帧?我尝试了 as.data.frame(lapply(list(Day1, Day2), rename_fun)),但是它变成了一个单独的数据框,同时包含 Day1 和 Day2。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 2021-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多