2016-08-23 5 views
0

У меня есть большой фрейм данных с первым столбцом, являющимся алфавитно-цифровыми именами строк. Я использую idx, как показано ниже, для выбора случайного выбора строк для каждого столбца (здесь 3 строки). Теперь мне нужно вычислить кумулятивную сумму для каждого idx [i, j]. Мой кадр данных огромен, поэтому функции в пакете plyr предпочтительнее ради времени вычисления. Любая идея, как мне рассчитать это?Как вычислить cumsum на основе имен строк, хранящихся в виде списка?

library(plyr) 

V1 <- c('t14','t23','t54', 't13', 't1','t102', 't104', 't245') 
V2 <- c(4.2, 5.3, 5.4,6, 7,8.5,9, 10.1) 
V3 <- c(5.1, 5.1, 2.4,6.1, 7.7,5.5,1.99, 5.42) 
my_df <- data.frame(V1, V2, V3) 

#The following line randomly select 3 rows for each column 
idx <- lapply(integer(ncol(my_df)-1), function(...) sample(my_df$V1, 3)) 

Благодаря

+1

«Мой кадр данных огромен, поэтому функции в пакете plyr предпочтительны ради времени вычисления» - это не имеет смысла. Вы используете plyr для своей простоты и простоты использования, а не потому, что он быстрый или масштабируемый для огромных наборов данных. –

ответ

1

Будем надеяться, что кто-то может предложить plyr решение (у меня нет большого опыта работы с этим пакетом). В то же время, здесь data.table решение, которое может быть столь же быстро (возможно, быстрее), как plyr:

library(plyr) 

V1 <- c('t14','t23','t54', 't13', 't1','t102', 't104', 't245') 
V2 <- c(4.2, 5.3, 5.4,6, 7,8.5,9, 10.1) 
V3 <- c(5.1, 5.1, 2.4,6.1, 7.7,5.5,1.99, 5.42) 
my_df <- data.frame(V1, V2, V3, stringsAsFactors = F) 

#The following line randomly select 3 rows for each column 
set.seed(100) # Setting seed so that this example is reproducible 
idx <- lapply(integer(ncol(my_df)-1), function(...) sample(my_df$V1, 3)) 

idx 

# Additional code 

# Import the data.table package - you'd want to move this line to the top of your code 
library(data.table) 
setDT(my_df) # Cast the data.frame to data.table 
setkey(my_df, V1) # Set the key for the data.table to V1 

# With the key set as V1, I can just call idx[[i]] as the first argument of my_df 
# This will map each value of idx[[i]] to the appropriate row based on V1 
# In the following, for the i-th vector in idx, I calculate the cumulative sum of each of V_{i + 1} 
myResult = lapply(1:length(idx), function(i){ 
     my_df[idx[[i]], lapply(.SD, cumsum), .SDcols = i + 1] 
    } 
) 

На данный момент, myResult список:

[[1]] 
    V2 
1: 5.4 
2: 10.7 
3: 16.7 

[[2]] 
    V3 
1: 5.1 
2: 11.2 
3: 13.6 

Мы создаем фрейм данных следующим образом:

# Column bind to create matrix of results 
myResult = do.call(cbind, myResult) 

результат выглядит следующим образом:

 V2 V3 
1: 5.4 5.1 
2: 10.7 11.2 
3: 16.7 13.6 
+0

Спасибо @Jav за то, что вы потратили время и силы на это. Я думаю, что мне не нужно преобразовывать idx в вектор, так как мне нужен idx для двух измерений. Как вы могли заметить, одинаковые имена строк имеют разные значения в разных столбцах, поэтому конечный вывод предполагает наличие суммарной суммы для каждого столбца в отдельных столбцах. В случае этого примера один столбец, содержащий ('t54', 't54' + 't23', t54 '+' t23 '+' t13 ') для V2, а другой столбец содержит значения ("t14", "t14" + "t13", "t14" + "t13" + "t54") для столбца V3. – vahab

+0

Мои извинения, я исправил в основном последнюю строку кода, чтобы отразить суммарную сумму. Я также оставил idx в списке. Дайте мне знать, если вывести выше, что вы ожидаете. – jav

+0

Кроме того, если это необходимо обобщать для большего количества столбцов, дайте мне знать, и я могу соответствующим образом отредактировать приведенное выше. – jav