#r #matrix
#r #матрица
Вопрос:
Я использую следующий фрейм данных в R:
ID <- c(LETTERS[1:10])
GLUC <- c(88,NA,110,NA,90,88,120,110,NA,90)
TGL <- c(NA,150,NA,200,210,NA,164,170,190,NA)
HDL <- c(32,60,NA,65,NA,32,NA,70,NA,75)
LDL <- c(99,NA,120,165,150,210,NA,188,190,NA)
patient_num <- data.frame(ID,GLUC,TGL,HDL,LDL)
И я хочу создать матрицу, в которой в качестве имен строк указаны GLUC, TGL, HDL и LDL, а в качестве имен столбцов — среднее, медианное, sd, n и n_miss. Когда я ввожу следующий код:
r <- c(mean(patient_num[[varname]],na.rm=TRUE),
median(patient_num[[varname]],na.rm=TRUE),
sd(patient_num[[varname]],na.rm=TRUE),
sum(!is.na(patient_num[[varname]])),
sum(is.na(patient_num[[varname]]))
)
if (length(varname) == 1){
r <- matrix(r,nrow=T)
} else{
for (index in 2:length(varname)){
oneRow = table1(patient_num,varname[[index]])
r <- rbind(r,oneRow)
}
}
rownames(r) <- varname
colnames(r) <- c("mean","median","sd","n","n_miss")
return(r)
}
table1(patient_num,c("GLUC","TGL","HDL","LDL"))
Я получаю сообщение об ошибке:
Ошибка в .subset 2 (x, i, exact = exact): сбой рекурсивной индексации на уровне 2
Кажется, не могу понять, что не так
Ответ №1:
Есть более простое решение, использующее sapply()
from base R
:
new_df <- sapply(patient_num, function(x) list(
mean = mean(x, na.rm = T),
sd = sd(x, na.rm = T),
n = sum(!is.na(x)),
is_na = sum(is.na(x))))
t(new_df)
#> mean sd n is_na
#>ID NA NA 10 0
#>GLUC 99.42857 13.45185 7 3
#>TGL 180.6667 23.0362 6 4
#>HDL 55.66667 19.00175 6 4
#>LDL 160.2857 40.06126 7 3
Если вам нужно только количество записей, отличных от NA, в каждой строке, вы можете просто удалить ID
из patient_num
и запустить тот же код.
Обратите внимание, что вы можете захотеть преобразовать new_df
обратно в a data.frame
.
Ответ №2:
Вы можете выбирать только один столбец за раз, используя [[
.
Вот альтернативный способ с использованием dplyr
функций.
library(dplyr)
table1 <- function(data, varname) {
data %>%
select(all_of(varname)) %>%
tidyr::pivot_longer(cols = everything()) %>%
group_by(name) %>%
summarise(mean = mean(value, na.rm = TRUE),
median = median(value, na.rm = TRUE),
sd = sd(value, na.rm = TRUE),
n = sum(!is.na(value)),
n_miss = sum(is.na(value)))
}
table1(patient_num,c("GLUC","TGL","HDL","LDL"))
# A tibble: 4 x 6
# name mean median sd n n_miss
# <chr> <dbl> <dbl> <dbl> <int> <int>
#1 GLUC 99.4 90 13.5 7 3
#2 HDL 55.7 62.5 19.0 6 4
#3 LDL 160. 165 40.1 7 3
#4 TGL 181. 180 23.0 6 4