首页 > 解决方案 > 多个类似的 csv 文件中的相同功能并在单个 csv 文件中输出?

问题描述

R中的新手在这里。

我发现了关于我的问题的类似线程和教程,但是由于我无法找出解决问题的方法,并且随着我的项目截止日期临近,我想寻求帮助。

我在一个目录中有多个名称相似的 csv 文件(2fg、20fg、...)。它们都包含 8 列和 360 行的数据框。行代表时间,每列代表一系列测量值。

我想要做的是找到每列的平均值和 sd,然后是这 8 个平均值的集体平均值和 sd,最后绘制每个 csv 的时间序列(每条线具有不同的颜色)和比较集体平均值的直方图(和 sd)的所有 csv。

到目前为止,我能够找到平均值、sd 和它们的集合,并使用 plot.ts(2fg, plot.type=c("single"), col=rainbow(ncol(2fg)))

我正在寻找的是一种在我的目录中的每个 csv 上执行所有这些操作的方法,然后绘制直方图,该直方图将比较集体均值并在单个 xlsx 或 csv 文件上输出每个 csv 的图和集体均值和 sds。

我正在研究的方法是将我所有的 csvs 放在一个列表中,使用

list <- list.files(pattern = "csv") 

然后尝试使用 lapply 但我无法产生任何结果。

我希望我足够清楚,并提前感谢您的帮助!

编辑:按照@Len Greski 在评论中提出的建议,我将所有文件放在一个列表中,同时给我的数据一个标题

    lista <- list.files(pattern = ".csv", full.names=TRUE)
myfiles <- lapply(lista,function(x) {
  y <- read.csv(x,stringsAsFactors=FALSE, header = FALSE, sep = ',',
                col.names = c("well_1", "well_2", "well_3", "well_4", "well_5",
                "well_6", "well_7", "well_8"))
  y$filename <- x
  y 
})

然后在一个大数据框中

 data <- do.call(rbind,myfiles)

 
# A tibble: 6 x 9
    well_1 well_2 well_3 well_4 well_5 well_6 well_7 well_8 filename          
       <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl> <chr>             
    1  0.158  0.218  0.152  0.189  0.205  0.190  0.181  0.153 ./1_s1_control.csv
    2  0.158  0.218  0.152  0.189  0.205  0.190  0.181  0.153 ./1_s1_control.csv
    3  0.158  0.218  0.152  0.189  0.204  0.190  0.181  0.153 ./1_s1_control.csv
    4  0.158  0.218  0.152  0.189  0.204  0.190  0.181  0.153 ./1_s1_control.csv
    5  0.159  0.218  0.151  0.189  0.204  0.190  0.181  0.153 ./1_s1_control.csv
    6  0.159  0.218  0.151  0.189  0.204  0.190  0.181  0.153 ./1_s1_control.csv

然后我尝试了以下方法来计算均值和标准差,但出现错误

    # summarise by file (filename)
    data2 <- data %>% 
      group_by(filename) %>%
      summarise(., across(c(well_1, well_2, well_3, well_4, well_5, well_6, well_7, well_8)),
                         list(mean = mean, sd = sd), .names = "{col}.{fn}")

Error: `across()` must only be used inside dplyr verbs.
Run `rlang::last_error()` to see where the error occurred.
In addition: Warning message:
In names(cols)[missing_names] <- names[missing_names] :
  number of items to replace is not a multiple of replacement length

欢迎任何建议或更正!:)

标签: rcsvplotdata-analysis

解决方案


这是一个如何完成问题中所有任务的示例,除了绘制时间序列和直方图。由于该问题没有提供可重复的示例,我们将使用我保存在 Github 上的Pokémon Stats数据,该数据最初基于 Alberto Barradas 的 Kaggle 数据集。

每个文件包含一代神奇宝贝,gen01.csv通过gen07.csv. 所有文件都跟踪代表神奇宝贝基本统计数据的 13 个变量,如下图所示。

在此处输入图像描述

首先,我们将下载数据,解压缩 zip 文件,获取文件名列表,然后使用lapply()read.csv() 读取它们。

if(!file.exists("pokemonData.zip")){
     download.file("https://raw.githubusercontent.com/lgreski/pokemonData/master/pokemonData.zip",
                   "pokemonData.zip",
                   method="curl",mode="wb")
     unzip("pokemonData.zip")
}

thePokemonFiles <- list.files("./pokemonData",pattern="*.csv",
                              full.names=TRUE)

pokemonDataFiles <- lapply(thePokemonFiles,function(x) {
    y <- read.csv(x,stringsAsFactors=FALSE)
    # uncomment next line to add a column that stores the file name
    # y$fileName <- x
    y 
})

接下来,我们将七个数据帧组合成一个数据帧do.call()

# merge to single data frame
data <- do.call(rbind,pokemonDataFiles)

由于每个文件都包含一个Generation映射到文件的列,我们可以使用这个变量dplyr::group_by()来计算文件的平均值和标准差。

library(dplyr)
# summarise by file (generation)
data %>% group_by(Generation) %>%
     summarise(.,across(c(Total,HP,Attack,Defense,SpecialAtk,SpecialDef,Speed),
                        list(mean = mean, sd = sd), .names = "{col}.{fn}")) 


# A tibble: 7 x 15
  Generation Total.mean Total.sd HP.mean HP.sd Attack.mean Attack.sd Defense.mean
       <int>      <dbl>    <dbl>   <dbl> <dbl>       <dbl>     <dbl>        <dbl>
1          1       426.     115.    65.6  28.1        76.5      30.8         70.7
2          2       418.     120.    71.2  30.6        72.0      32.7         73.4
3          3       436.     136.    66.5  24.1        81.6      36.6         74.1
4          4       459.     120.    73.1  25.1        82.9      32.8         78.1
5          5       435.     108.    71.8  22.4        82.1      30.4         72.3
6          6       436.     115.    68.3  20.9        75.8      29.2         76.7
7          7       461.     123.    71.3  26.9        87.1      33.9         79.3
# … with 7 more variables: Defense.sd <dbl>, SpecialAtk.mean <dbl>,
#   SpecialAtk.sd <dbl>, SpecialDef.mean <dbl>, SpecialDef.sd <dbl>,
#   Speed.mean <dbl>, Speed.sd <dbl>

我们可以通过消除group_by()dplyr 管道中的函数来计算文件间的均值和标准差。

# summarise across generations
summarise(data,across(c(Total,HP,Attack,Defense,SpecialAtk,SpecialDef,Speed),
               list(mean = mean, sd = sd), .names = "{col}.{fn}")) 


  Total.mean Total.sd  HP.mean  HP.sd Attack.mean Attack.sd Defense.mean
1   437.6293 120.4411 69.43561 25.665    79.82643  32.70236     74.39194
  Defense.sd SpecialAtk.mean SpecialAtk.sd SpecialDef.mean SpecialDef.sd
1   31.32974        73.39866      33.11673        72.37066      27.96375
  Speed.mean Speed.sd
1   68.20605 29.28088
> 

为了解决问题的绘图部分,我们需要发布问题的人提供更多信息。


推荐阅读