在For Loop R中处理迭代的CSV文件

时间:2019-03-21 17:33:53

标签: r for-loop

感谢您的帮助!这是我在做什么的描述。

我有一个分类问题,需要根据填充传感器数据的csv文件对运动动作进行分类。

主要训练集如下:

    > head(main_train)
    Subject                            Datafile                   Label
1 Subject02 Subject02/Subject02_Aufnahme000.csv         curve-left-step
2 Subject02 Subject02/Subject02_Aufnahme001.csv         curve-left-step
3 Subject02 Subject02/Subject02_Aufnahme002.csv            stand-to-sit
4 Subject02 Subject02/Subject02_Aufnahme003.csv curve-right-spin-Rfirst
5 Subject02 Subject02/Subject02_Aufnahme004.csv            jump-one-leg
6 Subject02 Subject02/Subject02_Aufnahme005.csv   lateral-shuffle-right

我设法像下面这样遍历这些文件:

csv <- list.files(path = "Subjects/Subject02/", pattern = ".csv", full.names = TRUE)

我想先将数据集划分为四分之一,从四分之一的每一列中提取均值,中位数,sd,max和min,然后获得带有mean_1,m​​ean_2,mean_3,mean,_4的一行...

然后,我可以插入新的行数据来代替Datafile值(一旦获得上述内容就没问题了。

我正在使用For循环,但是我尝试了 EVERYTHING (很好,很愉快,但是那些函数之间,...)。我的结果应返回440行以获取csv文件的数量,但是,在此版本上,我只能返回一行。我会为此寻求帮助。另外,我认为这是一个有趣的难题,应该与其他循环问题相关。

这是我的代码:

for(i in csv) { 
  dataset <- read.csv(i)

  first = round(nrow(dataset)/4)
  second = 2 * round(nrow(dataset)/4)
  third = 3 * round(nrow(dataset)/4)

  dataset_1 = dataset[1:first,]
  dataset_2 = dataset[first:second,]
  dataset_3 = dataset[second:third,]
  dataset_4 = dataset[third:nrow(dataset),]

  for (v in dataset_1){
    mean_1 = mean(v)
    median_1 = median(v)
    sd_1 = sd(v)
    min_1 = min(v)
    max_1 = max(v)
  }
  for (v in dataset_2){
    mean_2 = mean(v)
    median_2 = median(v)
    sd_2 = sd(v)
    min_2 = min(v)
    max_2 = max(v)
  }
  for (v in dataset_3){
    mean_3 = mean(v)
    median_3 = median(v)
    sd_3 = sd(v)
    min_3 = min(v)
    max_3 = max(v)
  }
  for (v in dataset_1){
    mean_4 = mean(v)
    median_4 = median(v)
    sd_4 = sd(v)
    min_4 = min(v)
    max_4 = max(v)
  }

  subject_data <- cbind(mean_1, mean_2, mean_3, mean_4,
                        median_1, median_2, median_3, median_4,
                        sd_1, sd_2, sd_3, sd_4,
                        min_1, min_2, min_3, min_4,
                        max_1, max_2, max_3, max_4)
}

,结果只有一行,需要为440:

    > subject_data
       mean_1   mean_2   mean_3   mean_4 median_1 median_2 median_3 median_4     sd_1     sd_2     sd_3     sd_4 min_1 min_2
[1,] 33280.73 36429.69 35986.18 33280.73    33709    36904    35264    33709 1957.654 1797.988 4484.521 1957.654 29328 32184
     min_3 min_4 max_1 max_2 max_3 max_4
[1,] 22768 29328 38320 38320 46456 38320

1 个答案:

答案 0 :(得分:1)

我自己处理运动数据,我建议您使用不同的数据结构。我真的认为这将使您将来的数据分析更加轻松。

关于行数-我认为这段代码将使查明数据中的任何潜在错误变得更加容易。

首先,我构建一些数据来模拟您的结构。我只创建了三个.csv文件。

library(tidyverse)
library(here)

#Create some csv files
curve_left_step = rnorm(16, 0, 1)
stand_to_sit = rnorm(16, 20, 2)
jump_one_leg = rnorm(16, 15, 1)

write.csv(curve_left_step, here("Subject02_Aufnahme000.csv"))
write.csv(stand_to_sit, here("Subject02_Aufnahme002.csv"))
write.csv(jump_one_leg, here("Subject02_Aufnahme004.csv"))

我使用purrr将这些文件导入R。这将所有数据保留在一个数据帧中。我还添加了一个标签列。

#Import the csv files into R using purrr
data_all <- tibble(
  path = list.files(path = here(), pattern = "Subject", full.names = TRUE)) %>% 
  mutate(
    data = map(.x=path, ~read.csv(file = .x)),
    label = c("curve_left_step", "stand_to_sit", "jump_one_leg"))

这种数据结构的优势在于您可以将函数应用于data_all对象中的小型数据集(数据列)。

首先,我们创建一个这样的函数:

#Create a function that splits the data into 4 and keeps a selected quarter
split_and_calc <- function(.data, ...){
  .data %>%
    #Divide into quarters
    mutate(
      quarter = ceiling(row_number()/4)) %>% 
    #Select the quarter of interest  
    filter(quarter == ...) %>%
    #Select the variable of interest. here it is [[2]], but in your data this is likely different
    select(2) %>% 
    summarise_all(.funs = c("mean", "median", "sd", "min", "max"))
}

现在,我们将函数应用于数据列中的所有小型数据框:

#Apply the function to all dataframes in data column in data_all
data_all <- data_all %>% 
  mutate(
    quarter1 = map(.x=data, ~split_and_calc(.x, 1)),
    quarter2 = map(.x=data, ~split_and_calc(.x, 2)),
    quarter3 = map(.x=data, ~split_and_calc(.x, 3)),
    quarter4 = map(.x=data, ~split_and_calc(.x, 4)))


> data_all
# A tibble: 3 x 7
  path                                                          data               label         quarter1           quarter2          quarter3          quarter4         
  <chr>                                                         <list>             <chr>         <list>             <list>            <list>            <list>           
1 C:/Users/sharsted/OneDrive/R/R club/Facebook help/Subject02_~ <data.frame [16 x~ curve_left_s~ <data.frame [1 x ~ <data.frame [1 x~ <data.frame [1 x~ <data.frame [1 x~
2 C:/Users/sharsted/OneDrive/R/R club/Facebook help/Subject02_~ <data.frame [16 x~ stand_to_sit  <data.frame [1 x ~ <data.frame [1 x~ <data.frame [1 x~ <data.frame [1 x~
3 C:/Users/sharsted/OneDrive/R/R club/Facebook help/Subject02_~ <data.frame [16 x~ jump_one_leg  <data.frame [1 x ~ <data.frame [1 x~ <data.frame [1 x~ <data.frame [1 x~

您来自各个.csv文件的数据现在存储在data列中,而Quarter1包含数据四分之一的平均值,中位数,sd,min和max,同样包含Quarter2、3和4的平均值。 / p>

假设您现在要访问Quarter1的汇总值。您可以执行以下代码:

data_all %>% 
  select(label, quarter1) %>% 
  unnest()
# A tibble: 3 x 6
  label              mean  median    sd    min    max
  <chr>             <dbl>   <dbl> <dbl>  <dbl>  <dbl>
1 curve_left_step  -0.360  -0.384 0.833  -1.13  0.458
2 stand_to_sit     20.9    21.0   2.09   18.9  22.8  
3 jump_one_leg     14.9    15.0   0.315  14.5  15.2