#r #for-loop
#r #цикл for
Вопрос:
спасибо за помощь! Вот описание того, что я делаю.
У меня проблема с классификацией, когда мне нужно классифицировать спортивные движения в соответствии с 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, mean_2, mean_3, mean,_4…
Затем я могу вставить новые данные строки вместо значения файла данных (что не является проблемой, как только я смогу получить вышеупомянутое.
Я использую циклы For, но я перепробовал ВСЕ (lapply, sapply, но из тех, у которых есть функции между, …) . Мой результат должен возвращать 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. Я думаю, что с этой задачей лучше всего справиться с помощью purrr — Вы знакомы с этим пакетом?
2. Я не знаком и не использовал это, но я видел, как это упоминалось в некоторых связанных вопросах, и определенно попытаюсь реализовать это сейчас. Спасибо!!
3. Добро пожаловать. Это также решило вашу проблему с количеством строк?
4. @SteenHarsted Я думаю, что существует серьезная проблема с RStudio и копированием и вставкой. В итоге я буквально перепечатал все слово в слово, и это сработало. Не уверен, почему, и много часов потратил на возню. Но в конечном итоге код заработал в этом смысле.
Ответ №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"))
Я импортирую эти файлы в R с помощью purrr. Это сохраняет все данные в одном фрейме данных. Я также добавляю столбец label.
#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 для 1 квартала данных, а также для quarter2, 3 и 4.
Допустим, теперь вы хотите получить доступ к своим итоговым значениям из 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
Комментарии:
1. Привет @marc_s, что ты имеешь в виду, говоря «выбрать интересующую переменную» и «выбрать (2)»?
2. Привет @MargiSant , в этой строке выбирается один столбец из импортированного csv-файла. Затем этот столбец используется для вычисления нужной вам описательной статистики. В созданных мной данных интересующий столбец является вторым — следовательно
select(2)
. Я не знаю вашу структуру данных в файле csv, но если у вас есть только один столбец, вы можете пропустить строку выбора.