【问题标题】:Same functions on multiple similar csv files and output in a single csv file?多个相似的 csv 文件中的相同功能并在单个 csv 文件中输出?
【发布时间】:2020-10-25 04:11:32
【问题描述】:

这里是 R 的新手。

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

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

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

到目前为止,我能够找到平均值、标准差和它们的集合,并绘制单个 csv 文件的时间序列,使用 plot.ts(2fg, plot.type=c("single"), col=rainbow(ncol(2fg)))

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

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

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

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

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

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

    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

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

    # 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

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

【问题讨论】:

标签: r csv plot data-analysis


【解决方案1】:

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

每个文件包含一代神奇宝贝,gen01.csvgen07.csv。所有文件都跟踪代表 Pokémon 基本统计数据的 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>

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

# 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
> 

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

【讨论】:

  • 非常感谢您的建议!我编辑了我的原始问题,以包括我到目前为止所做的事情以及描绘我部分数据的图像。如果您有任何其他建议,我将非常乐意听到!
  • @greg - 您的代码失败,因为您放错了右括号,这是一个微妙的错误。试试这个: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}"))
  • 你对括号是绝对正确的!现在它工作得很好非常感谢!
  • @greg - 如果您发现我的回答有帮助,请勾选答案旁边的复选标记并点赞以接受它。
猜你喜欢
  • 2013-06-24
  • 1970-01-01
  • 2021-09-24
  • 1970-01-01
  • 2021-04-30
  • 2021-09-28
  • 2017-04-24
  • 2020-12-13
  • 2017-12-01
相关资源
最近更新 更多