Изменить столбцы, просматривая список элементов - PullRequest
0 голосов
/ 10 апреля 2020

Я создал 8 фрагментов из файлов CSV. Каждый столбик имеет общий столбец person_id. Значения в person_id являются целыми числами, и я хотел бы, чтобы они были факторами.

Я использую tidyverse

Импорт

drugs <- as_tibble(read.csv("../raw_data/icu_covid_sample/icu_sample_drugs.csv"))
flowsheet_dirty <- as_tibble(read.csv("../raw_data/icu_covid_sample/icu_sample_flowsheet_dirty.csv"))
measurements_clean <- as_tibble(read.csv("../raw_data/icu_covid_sample/icu_sample_measurements_clean.csv"))
measurements_dirty <- as_tibble(read.csv("../raw_data/icu_covid_sample/icu_sample_measurements_dirty.csv"))
procedures_cpt <- as_tibble(read.csv("../raw_data/icu_covid_sample/icu_sample_procedures_cpt.csv"))
vent_dirty <- as_tibble(read.csv("../raw_data/icu_covid_sample/icu_sample_vent_dirty.csv"))
visits <- as_tibble(read.csv("../raw_data/icu_covid_sample/icu_sample_visits.csv"))
person <- as_tibble(read.csv("../raw_data/icu_covid_sample/sample_icu_person.csv"))

Создание списка

data_list <- list(drugs = drugs, flowsheet_dirty = flowsheet_dirty, measurements_clean = measurements_clean, measurements_dirty = measurements_dirty, procedures_cpt = procedures_cpt, vent_dirty = vent_dirty, visits = visits, person = person)

Некоторые выходные данные:

> summary(data_list)
                   Length Class  Mode
drugs              12     tbl_df list
flowsheet_dirty    38     tbl_df list
measurements_clean 13     tbl_df list
measurements_dirty 13     tbl_df list
procedures_cpt      4     tbl_df list
vent_dirty         12     tbl_df list
visits             18     tbl_df list
person             39     tbl_df list

В каждом столбце списка есть столбец "person_id"

ex. наркотики $ person_id, посещения $ person_id, et c.

> seq_along(data_list)
[1] 1 2 3 4 5 6 7 8

Я хотел бы повторить с a для l oop, чтобы преобразовать каждый столбец person_id в факторные данные, а не в целое число. В более общем смысле, я хочу знать, как применять функции к группе тиблей, располагая их в списке.


for (i in seq_along(data_list)) {
  data_list[i]$person_id <- as.factor(data_list[i]$person_id)
}

Вывод ошибки:

number of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement lengthnumber of items to replace is not a multiple of replacement length

Один тест (должен быть сделано до l oop ошибка)

data_list$drugs$person_id <- as.factor(data_list$drugs$person_id)

> is.factor(data_list$drugs$person_id)
[1] TRUE
> is.factor(data_list$visit$person_id)
[1] FALSE

Это также не работает:


for (i in seq_along(data_list)) {
  data_list[[i]]$person_id <- as.factor(data_list[[i]]$person_id)
}

Ошибка:

Unknown or uninitialised column: `person_id`.Error: Assigned data `as.factor(data_list[[i]]$person_id)` must be compatible with existing data.
x Existing data has 6 rows.
x Assigned data has 0 rows.
i Only vectors of size 1 are recycled.
Run `rlang::last_error()` to see where the error occurred.

> rlang::last_error()
<error/tibble_error_assign_incompatible_size>
Assigned data `as.factor(data_list[[i]]$person_id)` must be compatible with existing data.
x Existing data has 6 rows.
x Assigned data has 0 rows.
i Only vectors of size 1 are recycled.
Backtrace:
 1. base::`$<-`(`*tmp*`, "person_id", value = structure(integer(0), .Label = character(0), class = "factor"))
 2. tibble:::`$<-.tbl_df`(`*tmp*`, "person_id", value = structure(integer(0), .Label = character(0), class = "factor"))
 3. tibble:::tbl_subassign(...)
 4. tibble:::vectbl_recycle_rhs(...)
 5. base::tryCatch(...)
 6. base:::tryCatchList(expr, classes, parentenv, handlers)
 7. base:::tryCatchOne(expr, names, parentenv, handlers[[1L]])
 8. value[[3L]](cond)
Run `rlang::last_trace()` to see the full context.

> rlang::last_trace()
<error/tibble_error_assign_incompatible_size>
Assigned data `as.factor(data_list[[i]]$person_id)` must be compatible with existing data.
x Existing data has 6 rows.
x Assigned data has 0 rows.
i Only vectors of size 1 are recycled.
Backtrace:
    x
 1. +-base::`$<-`(`*tmp*`, "person_id", value = structure(integer(0), .Label = character(0), class = "factor"))
 2. \-tibble:::`$<-.tbl_df`(`*tmp*`, "person_id", value = structure(integer(0), .Label = character(0), class = "factor"))
 3.   \-tibble:::tbl_subassign(...)
 4.     \-tibble:::vectbl_recycle_rhs(...)
 5.       \-base::tryCatch(...)
 6.         \-base:::tryCatchList(expr, classes, parentenv, handlers)
 7.           \-base:::tryCatchOne(expr, names, parentenv, handlers[[1L]])
 8.             \-value[[3L]](cond)
>

Так что я знаю, что с 8 команд Я могу преобразовать столбцы person_id в целые числа, но у меня возникают проблемы с этим в al oop. Кроме того, возможно, mutate () мог бы помочь мне, однако я хотел бы быть легким с итерациями. Кроме того, я не уверен, что мой data_list должен быть списком. Возможно, это должен быть вектор или что-то еще. Любая помощь приветствуется.

1 Ответ

1 голос
/ 10 апреля 2020

Здесь нам нужно выполнить извлечение с [[ вместо [, потому что [ возвращает list длины 1 и не извлекает данные

for (i in seq_along(data_list)) {
   data_list[[i]][["person_id"]] <- as.factor(data_list[[i]][["person_id"]])
  }

На основе показанная ошибка, могут быть наборы данных, у которых нет 'person_id'. В этом случае мы можем проверить 'person_id' и, если он присутствует, сделать следующий

for (i in seq_along(data_list)) {
   i1 <-  'person_id' %in% names(data_list[[i]])
   if(i1) {
    data_list[[i]]$person_id <- as.factor(data_list[[i]]$person_id)  
    }
}

В качестве воспроизводимого примера

lst1 <- list(as_tibble(head(mtcars)) %>% 
            mutate(person_id = 1:6), 
            as_tibble(head(iris)) %>%
               mutate(person_id = 1:6))
for(i in seq_along(lst1))  lst1[[i]]$person_id <- as.factor(lst1[[i]]$person_id)
is.factor(lst1[[1]]$person_id)
#[1] TRUE

Или это можно сделать с помощью lapply

data_list <- lapply(data_list, transform, person_id = as.factor(person_id))

или другой вариант map

library(dplyr)
library(purrr)
data_list <- map(data_list, ~ .x %>% 
                      person_id = factor(person_id))
...