Я хочу рассчитать дополнительный совокупный счет выживаемости для последующего отображения в гистограмме (без использования ggplot). Например, подсчитайте количество элементов, сохранившихся за 4,0 года, 4,5 года, 5,0 года и т. Д.
Ввод данных - 10000 строк данных с 4 различными типами с 4 различными распределениями ожидаемой продолжительности жизни:
type <- c(rep("A",1000), rep("B",2000), rep("C",3000), rep("D",4000))
age <- c(rnorm(1000,6,0.5), rnorm(2000,8,0.5), rnorm(3000,10,0.5), rnorm(4000,12,0.5))
input <- data.frame(type,age,stringsAsFactors=FALSE)
Выходные данные построены с использованием диапазона для возрастных шагов:
range <- seq(floor(min(input$age)),ceiling(max(input$age)),0.5)
Я раскрываю в data.frame с диапазоном и типами:
combns <- expand.grid(age=range,type=LETTERS[1:4], stringsAsFactors=FALSE)
И затем использую функцию apply для подсчитайте общее число, превышающее каждый возрастной шаг:
CCSC.apply.all <- apply(combns[1:length(range),],1,function(x){
sum(input$age >= x["age"]) } )
и сгруппировано по типу:
CCSC.apply.type <- apply(combns,1,function(x){
sum(
input["age"] >= x["age"] &
input["type"] == x["type"]
) } )
В пределах функции применения input["age"] >= x["age"]
оценивается иногда неправильно. Это приводит к неправильному подсчету. В таблице ниже столбцы 2: 6 создаются с использованием apply, столбцы 7:11 с a для l oop. 2: 6 неправильные, 7:11 правильные.
> output
range all-apply A-apply B-apply C-apply D-apply all-for A-for B-for C-for D-for
1 4,0 10000 1000 2000 3000 4000 10000 1000 2000 3000 4000
2 4,5 10000 1000 2000 3000 4000 9998 998 2000 3000 4000
3 5,0 10000 1000 2000 3000 4000 9978 978 2000 3000 4000
4 5,5 10000 1000 2000 3000 4000 9843 843 2000 3000 4000
5 6,0 10000 1000 2000 3000 4000 9483 483 2000 3000 4000
6 6,5 10000 1000 2000 3000 4000 9141 143 1998 3000 4000
7 7,0 10000 1000 2000 3000 4000 8981 23 1958 3000 4000
8 7,5 10000 1000 2000 3000 4000 8690 2 1688 3000 4000
9 8,0 10000 1000 2000 3000 4000 8030 0 1030 3000 4000
10 8,5 10000 1000 2000 3000 4000 7329 0 330 2999 4000
11 9,0 10000 1000 2000 3000 4000 6989 0 43 2946 4000
12 9,5 10000 1000 2000 3000 4000 6528 0 2 2526 4000
13 10,0 10000 1000 2000 3000 4000 5494 0 0 1494 4000
14 10,5 8961 1000 2000 1967 3994 4455 0 0 461 3994
15 11,0 8485 1000 2000 1571 3914 3979 0 0 65 3914
16 11,5 7900 1000 2000 1510 3390 3394 0 0 4 3390
17 12,0 6515 1000 2000 1506 2009 2009 0 0 0 2009
18 12,5 5123 1000 2000 1506 617 617 0 0 0 617
19 13,0 4594 1000 2000 1506 88 88 0 0 0 88
20 13,5 4513 1000 2000 1506 7 7 0 0 0 7
21 14,0 4506 1000 2000 1506 0 0 0 0 0 0
Может кто-нибудь сказать мне, в чем проблема с моей функцией применения?
Дополнительное наблюдение: вопреки моим ожиданиям, применяется метод применения примерно в 100 раз медленнее, чем for-l oop.
Полный текст R приведен ниже:
rm(list=ls())
setwd("C:/R_test")
options(OutDec= ",") # to be deleted if not applicable for locale
set.seed(1234)
# creating input - data.frame 10000 data sets to be examined
# 4 different types with 4 different normal distributions for life expectancy
type <- c(rep("A",1000), rep("B",2000), rep("C",3000), rep("D",4000))
age <- c(rnorm(1000,6,0.5), rnorm(2000,8,0.5), rnorm(3000,10,0.5), rnorm(4000,12,0.5))
input <- data.frame(type,age,stringsAsFactors=FALSE)
# complementary cumulative survival count (CCSC)
range <- seq(floor(min(input$age)),ceiling(max(input$age)),0.5) # range for evaluation
# method "apply"
apply_time <- system.time( {
combns <- expand.grid(age=range,type=LETTERS[1:4], stringsAsFactors=FALSE)
CCSC.apply.all <- apply(combns[1:length(range),],1,function(x){
sum(input$age >= x["age"]) } ) # count survivors of all types
CCSC.apply.type <- apply(combns,1,function(x){
sum( # count survivors of certain type
input["age"] >= x["age"] &
input["type"] == x["type"]
) } )
})
output <- data.frame(range, matrix(c(CCSC.apply.all,CCSC.apply.type), nrow=length(range)))
# method "for loop"
for_time <- system.time( {
CCSC.for.all <- rep(0.0, length(range))
CCSC.for.type <- matrix(rep(0.0, 4*length(range)),nrow=length(range))
for(i in 1:length(range))
{
CCSC.for.all[i] <- sum(input$age >= range[i])
for(j in 1:4)
{
CCSC.for.type[i,j] <-
sum(
input["age"] >= range[i] &
input["type"] == LETTERS[j]
)
}
}
})
output <- cbind(output,CCSC.for.all,CCSC.for.type)
colnames(output) <- c("range",
"all-apply","A-apply","B-apply","C-apply","D-apply",
"all-for","A-for","B-for","C-for","D-for")
cat("\ntime for apply method: ", apply_time)
cat("\ntime for for loop method: ", for_time, "\n\n")
write.table(input, file = "CCSC_input.csv", sep=";", row.names=FALSE, dec=",")
write.table(output, file = "CCSC_output.csv", sep=";", row.names=FALSE, dec=",")