2014-02-07 2 views
1

Я пытаюсь объединить некоторые данные и я хотел бы взять пропорции некоторых переменных и сделать их значения в столбцах, как показано нижеПостроение списка выражений в цикле в R

library(data.table) 
testDT <- data.table(z=sample(1:5, 2500000, replace=TRUE), a=sample(1:20, 2500000, replace=TRUE), b=sample(1:30, 2500000, replace=TRUE), c=sample(1:10, 2500000, replace=TRUE)) 
setkey(testDT, z) 
testDT.AG=testDT[, list(
        a_Mean=mean(as.numeric(a), na.rm = TRUE), 
        a_1_prop=length(which(a==1))/length(which(a>0)), 
        a_2_prop=length(which(a==2))/length(which(a>0)), 
        a_3_prop=length(which(a==3))/length(which(a>0)), 
        a_4_prop=length(which(a==4))/length(which(a>0)), 
        a_5_prop=length(which(a==5))/length(which(a>0)), 
        a_6_prop=length(which(a==6))/length(which(a>0)), 
        a_7_prop=length(which(a==7))/length(which(a>0)), 
        a_8_prop=length(which(a==8))/length(which(a>0)), 
        a_9_prop=length(which(a==9))/length(which(a>0)), 
        a_10_prop=length(which(a==10))/length(which(a>0)) 
       ), by=list(z)] 

Я хотел бы построить этот список с петлей, как показано ниже:

testDT.AG=testDT[, list(
         a_Mean=mean(as.numeric(a), na.rm = TRUE), 
         for (i in c(1:10)) 
         { 
         assign(paste("a_", i, "_prop"), length(which(a==i))/length(which(a>0))), 
         } 
        ), by=list(z)] 

, но это не работает ...

есть в любом случае, чтобы построить список выражений, как это в цикле?

Спасибо заранее!

ответ

1

Я сделал свой пример немного меньше для тестирования, но вы должны быть в состоянии масштабировать его без труда:

testDT <- data.table(z=sample(1:5, 2500, replace=TRUE), a=sample(1:20, 2500, replace=TRUE), b=sample(1:10, 2500, replace=TRUE), c=sample(1:10, 2500, replace=TRUE)) 
setkey(testDT, z) 
prct.i <- function(a,i) sum(a==i)/sum(a>0) 
testDT[ , setNames(lapply(1:3, prct.i, a=a), paste0("a_", 1:3, "_prop")), by=z] 

    z a_1_prop a_2_prop a_3_prop 
1: 1 0.04373757 0.04970179 0.05964215 
2: 2 0.04678363 0.01949318 0.04483431 
3: 3 0.04158416 0.06534653 0.05742574 
4: 4 0.05296610 0.04872881 0.05084746 
5: 5 0.05128205 0.04142012 0.04930966 

Два «фокусы»: с помощью lapply возвращать список и setNames назвать иначе неназванный список. К сожалению и несколько иронично для функционального языка, в R цикл for всегда возвращает NULL. Я позже понял, что мне нужно, чтобы добавить обратно средства:

testDT[ , c(a_Mean=mean(as.numeric(a), na.rm = TRUE), 
      setNames(lapply(1:3, prct.i, a=a), paste0("a_", 1:3, "_prop")) 
      ), by=z] 
    z a_Mean a_1_prop a_2_prop a_3_prop 
1: 1 10.62227 0.04373757 0.04970179 0.05964215 
2: 2 10.93762 0.04678363 0.01949318 0.04483431 
3: 3 10.50495 0.04158416 0.06534653 0.05742574 
4: 4 10.64619 0.05296610 0.04872881 0.05084746 
5: 5 10.75937 0.05128205 0.04142012 0.04930966 

Я проверил значение против укороченной и более эффективной версии исходного кода:

testDT[, list(
        a_Mean=mean(as.numeric(a), na.rm = TRUE), 
        a_1_prop=sum(a==1)/sum(a>0), 
        a_2_prop=sum(a==2)/sum(a>0), 
        a_3_prop=sum(a==3)/sum(a>0) 
       ), by=list(z)] 
    z a_Mean a_1_prop a_2_prop a_3_prop 
1: 1 10.62227 0.04373757 0.04970179 0.05964215 
2: 2 10.93762 0.04678363 0.01949318 0.04483431 
3: 3 10.50495 0.04158416 0.06534653 0.05742574 
4: 4 10.64619 0.05296610 0.04872881 0.05084746 
5: 5 10.75937 0.05128205 0.04142012 0.04930966 
+0

Совершенных, спасибо так много! – user2386854

Смежные вопросы