【问题标题】:How can I loop through multiple dataframes, for a list of strings, search for columns containing string and create multiple new files?如何遍历多个数据框,查找字符串列表,搜索包含字符串的列并创建多个新文件?
【发布时间】:2015-09-30 13:54:18
【问题描述】:

我有 24 个数据文件 (bsls)。每个文件包含固定数量的行但可变数量的列 (sites)。我有 23 个sites 的干净列表,但由于与每个站点相关的列名包含其他信息,因此无法进行完全匹配。

我已使用以下代码将这些文件读入R

#list files from dir and read, skipping rows until 'Q Num'
temp <- list.files() # e.g. info-stuff-nameofbsl-otherStuff.csv

# read.xls and strip bsl name from file and assign as object name
for(i in temp){
    assign(unlist(strsplit(i, split = '-', fixed = T))[3],
           read.xls(i, pattern = "Q Num"))
}

#create list of dataframes (24 bsls)
bsls <- Filter(function(x) is(x, "data.frame"), mget(ls()))

#clean list of site names
sites <- ("NewYork","London","Sydney","Paris","Manchester","Angers","Venice","Bangkok","Glasgow","Boston","Perth","Canberra","Lyons","Washington","Milan","Cardiff","Dublin","Frankfurt","Ottawa","Toronto","El.Salvador","Taltal","Caldera")

24 个bsls 数据集的1 个的前3 行示例

例如BSL1

QNum,   QuestionText,   % unrelatedCol, NewYork_Other_info, London_some_other_info, Venice_other_diff_info, 
q17a,   question?,                 74%,              69%,                     81%,                  76%,
q17b,   Another question?,         72%,              73%,                     77%,                  74%,

我需要的结果是 23 个 sites 中的每一个都有一个 .csv 文件,其中包含在 24 个数据文件 (bsls) 中找到的所有列。

我目前的尝试...

for(site in sites){                             #for each site
    assign(site, data.frame())                  #create empty data frame to add vectors to
    for(bsl in dfs){                            #for each dataset
        if (grepl(site, colnames(bsl))){        #substring match
           next                                 #go back to for loop
        }
    assign(site$bsl, bsl[,grepl("site", colnames(bsl))]) #assign column to dataframe
    } 
}

解决方案如下所示...

例如 London.csv

QNum,   QuestionText, BSLname1_Other_info,  BSLname2_some_other_info, BSL5other_diff_info, 
q17a,   question?,                 74%,              69%,                     81%,                  76%,
q17b,   Another question?,         72%,              73%,                     77%,                  74%,

将有 23 个文件,每个站点一个,包含来自 24 个输入 bsl 文件的与站点相关的列。

编辑 - 值得一提的是,每个 bsls 不被称为 bsl1bsl2... 等,但实际上是唯一的字符串,例如unit,section,team...等

【问题讨论】:

    标签: r for-loop


    【解决方案1】:
    library(dplyr)
    library(stringi)
    library(tidyr)
    
    
    bind_rows(bsls, .id = bsl) %>%
      gather(variable, value, 
             matches(sites %>% paste(collapse = "|") ), 
             na.rm = TRUE ) %>%
      separate(variable, c("site", "new_variable", 
               sep = "_", extra = "merge") %>%
      unite(final_variable, bsl, new_variable, sep = "_") %>%
      spread(final_variable, value) %>%
      group_by(site) %>%
      do(write.csv(., paste("site", first(.$site), ".csv") ) )
    

    【讨论】:

    • 感谢@bramtayl 的尝试。几点。 gather 需要 library(tidyr)bind_rows(bsls) 不起作用,因为每个 bsl 数据集的列数各不相同。我尝试使用确实绑定的bind_cols(bsls),但是,对于新的site 数据集,我需要知道每列来自哪个bsl 数据集。 IE。列需要包含它来自的 bsl 数据集的名称。
    • bind_rows 应该确实可以工作,即使列数不同。我添加了 .id 以便您应该能够保留 bsls 信息。还添加了 na.rm 参数来收集。
    • Error: object 'variable' not found。此外,每个站点 Site 都有一个唯一的名称,例如("NewYork", "London", "Sydney" .... etc) 所以starts_with("Site") 将不起作用。对此我深表歉意,我将更新问题以反映唯一名称。
    • 可能值得一提的是,BSLs 也是唯一的字符串。
    • 好的,编辑希望能处理不同的站点名称。 bsls 列表的名称将出现在最后的变量名称中,因此只需选择最有意义的名称即可。
    【解决方案2】:

    以下代码最终解决了我的问题。我首先必须通过重命名 for loop 之前的数据框列表中的所有列来进一步分解原始问题。这是为了知道bsl 属于哪个site - 重命名逻辑可以在here 中找到。

    循环解决方案

    #this loop prints the files
    for (site in sites){
        #create new file with question cols only
        newfile <- data.frame(NewYork[,1:2], stringsAsFactors = F)
        # search for columns in bsls relating to site
        for (bsl in bsls){
            colids <- grepl(site, colnames(bsl))
            cols <- bsl[,colids, drop = F]
            newfile <- cbind(newfile, cols)
            }
        filename <- paste0("Site ", site," .csv")
        write.xlsx(newfile, file = filename, row.names = F)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-29
      • 2017-02-12
      • 2023-03-20
      • 2018-01-13
      • 2016-08-21
      • 2021-11-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多