Использование lapply для преобразования одного столбца данных в число чисел c в списке данных. - PullRequest
1 голос
/ 21 января 2020

У меня есть список данных, каждый из которых имеет три столбца, каждый из которых имеет тип character. Я хочу использовать lapply (или другую функцию *apply) и as.numeric для преобразования столбца «сердечный приступ» в число c, но также для сохранения других переменных в каждом кадре данных.

Вот примерные данные:

data <- structure(list(AK = structure(list(hospital = c("HOS_3", "HOS_4"
), state = c("AK", "AK"), `heart attack` = c("13.4", "17.7")), .Names = c("hospital", 
"state", "heart attack"), row.names = 3:4, class = "data.frame"), 
AL = structure(list(hospital = c("HOS_1", "HOS_2"), state = c("AL", 
"AL"), `heart attack` = c("14.3", "18.5")), .Names = c("hospital", 
"state", "heart attack"), row.names = 1:2, class = "data.frame"), 
AR = structure(list(hospital = c("HOS_5", "HOS_6"), state = c("AR", 
"AR"), `heart attack` = c("15.6", "16.9")), .Names = c("hospital", 
"state", "heart attack"), row.names = 5:6, class = "data.frame")), .Names = c("AK", 
"AL", "AR"))

Выглядит так:

> data
$AK
hospital state heart attack
3    HOS_3    AK         13.4
4    HOS_4    AK         17.7

$AL
hospital state heart attack
1    HOS_1    AL         14.3
2    HOS_2    AL         18.5

$AR
hospital state heart attack
5    HOS_5    AR         15.6
6    HOS_6    AR         16.9

Я хочу вернуть ту же самую структуру, но только с колонкой «инфаркт» как цифра c. Вот то, что я пробовал до сих пор (основываясь на других сообщениях SO, документах и ​​играх) и комментарий, объясняющий, что происходит не так:

lapply(c, function(x) x[3] <- as.numeric(x[[3]])) # returns list of num vectors. Dropped other cols
lapply(c, function(x) x[[3]] <- as.numeric(x[[3]])) # returns list of num vectors. Dropped other cols
rapply(c, as.numeric, classes = 'character', how='list') # Correct structure in output but converts all other cols to NA
sapply(c, function(x) x[,3] <- as.numeric(x[,3])) # returns list of num vectors. Dropped other cols
lapply(c, function(x) lapply(x[,3], as.numeric)) # returns list of num vectors of single length
lapply(c, lapply, as.numeric([[3]])) # error unexpected '[[
lapply(c, function(x) {x[[3]] <- as.numeric(x[[3]])})# returns list of num vectors. Dropped other cols
lapply(c, lapply, as.numeric, [,3]) # error unexpected '[

Помощь, высоко ценится! Кроме того, я хотел бы просто использовать базу R (если это возможно), поэтому предпочел бы не вводить другую библиотеку (проблемы безопасности на работе - они не всегда позволяют). Большое спасибо.

Ответы [ 3 ]

2 голосов
/ 21 января 2020

Другое решение base, которое объединяет lapply с within:

lapply(df_list, function(x) within(x,{`heart attack`<-
                               as.numeric(`heart attack`)}))
$AK
  hospital state heart attack
3    HOS_3    AK         13.4
4    HOS_4    AK         17.7

$AL
  hospital state heart attack
1    HOS_1    AL         14.3
2    HOS_2    AL         18.5

$AR
  hospital state heart attack
5    HOS_5    AR         15.6
6    HOS_6    AR         16.9

Чтобы подтвердить, что вышеприведенное работает:

List of 3
 $ AK:'data.frame': 2 obs. of  3 variables:
  ..$ hospital    : chr [1:2] "HOS_3" "HOS_4"
  ..$ state       : chr [1:2] "AK" "AK"
  ..$ heart attack: num [1:2] 13.4 17.7
 $ AL:'data.frame': 2 obs. of  3 variables:
  ..$ hospital    : chr [1:2] "HOS_1" "HOS_2"
  ..$ state       : chr [1:2] "AL" "AL"
  ..$ heart attack: num [1:2] 14.3 18.5
 $ AR:'data.frame': 2 obs. of  3 variables:
  ..$ hospital    : chr [1:2] "HOS_5" "HOS_6"
  ..$ state       : chr [1:2] "AR" "AR"
  ..$ heart attack: num [1:2] 15.6 16.9

Для пользователей tidyverse мы может сделать то же самое следующим образом:

purrr::map(df_list,purrr::modify_at(~.x,3,as.numeric))
$AK
  hospital state heart attack
3    HOS_3    AK         13.4
4    HOS_4    AK         17.7

$AL
  hospital state heart attack
1    HOS_1    AL         14.3
2    HOS_2    AL         18.5

$AR
  hospital state heart attack
5    HOS_5    AR         15.6
6    HOS_6    AR         16.9
2 голосов
/ 21 января 2020

Опция с transform

data <- lapply(data, transform, `heart attack` = as.numeric(`heart attack`))
str(data)
#List of 3
# $ AK:'data.frame':    2 obs. of  3 variables:
#  ..$ hospital    : chr [1:2] "HOS_3" "HOS_4"
#  ..$ state       : chr [1:2] "AK" "AK"
#  ..$ heart.attack: num [1:2] 13.4 17.7
# $ AL:'data.frame':    2 obs. of  3 variables:
#  ..$ hospital    : chr [1:2] "HOS_1" "HOS_2"
#  ..$ state       : chr [1:2] "AL" "AL"
#  ..$ heart.attack: num [1:2] 14.3 18.5
# $ AR:'data.frame':    2 obs. of  3 variables:
#  ..$ hospital    : chr [1:2] "HOS_5" "HOS_6"
#  ..$ state       : chr [1:2] "AR" "AR"
#  ..$ heart.attack: num [1:2] 15.6 16.9

Или с использованием map с mutate

library(dplyr)
library(purrr)
map(data, ~ .x %>%
              mutate(`heart attack` = as.numeric(`heart attack`)))
2 голосов
/ 21 января 2020

Вы были очень близки, вам просто нужно вернуть полный фрейм данных после изменения одного столбца. Поэтому, если вы хотите изменить класс столбца по имени, сделайте

data <- lapply(data, function(x) {x$`heart attack` <- as.numeric(x$`heart attack`);x})

Или, если вы хотите изменить класс по позиции, сделайте

data <- lapply(data, function(x) {x[[3]] <- as.numeric(x[[3]]);x})
...