2017-10-15 80 views
1

我在數據幀rand_sample中有一列是數據幀列表。我想只提取數據幀到數據幀中進行計算,然後再添加這些計算作爲新列在rand_sample從數據幀列表中提取數據幀並執行計算

str(rand_sample[1, ]$times) 
List of 1 
$ :'data.frame': 13 obs. of 2 variables: 
    ..$ white: num [1:13] 1800 1834 1875 1897 1887 ... 
    ..$ black: num [1:13] 1800 1860 1946 2031 2114 ... 

一是指數看起來是這樣的:

> rand_sample[1:10,]$times 
[[1]] 
    white black 
1 1800 1800 
2 1834 1860 
3 1875 1946 
4 1897 2031 
5 1887 2114 
6 1839 2203 
7 1835 2282 
8 1880 2370 
9 1875 2400 
10 1892 2323 
11 1612 2356 
12 1622 2370 
13 1619 2370 

從本質上講,我想

for (i in 1:nrow(rand_sample)) { 
    current <- rand_sample[i, ]$times[[1]] 
    mW <- abs(diff(current$white)) 
    mB <- abs(diff(current$black)) 
    maxWhite <- max(mW) 
    minWhite <- min(mW) 
    maxBlack <- max(mB) 
    minBlack <- min(mB) 
    sdWhite <- sd(mW) 
    sdBlack <- sd(mB) 
    avgW <- mean(mW) 
    avgB <- mean(mB) 

    rand_sample[i, ]$maxWhite <- maxWhite 
    rand_sample[i, ]$minWhite <- minWhite 
    rand_sample[i, ]$maxBlack <- maxBlack 
    rand_sample[i, ]$minBlack <- minBlack 
    rand_sample[i, ]$sdWhite <- sdWhite 
    rand_sample[i, ]$sdBlack <- sdBlack 
    rand_sample[i, ]$avgTimeWhite <- avgW 
    rand_sample[i, ]$avgTimeBlack <- avgB 
} 

兩個問題:你可以在這個for環表示

  1. 如何從$timestamp的每個列表中提取數據幀?

    rand_sample$times[[1]] 
    

    讓我只是第一行。我希望能夠像做

    rand_samples$dataFrameTimes <- rand_sample$times[[1]] 
    

    ,使得新列只是dataframes的列,而不是一個包含一個數據框的列表。

  2. 如何通過更快的機制模擬for循環?運行for循環需要每行大約1秒。我有一個包含數千行的數據集,所以這是站不住腳的。

+0

請提供可重現的實例中,例如通過使用rand_sample'的'的子集'dput' – Djork

+0

數據是專有的。有另一種方法嗎? – Parseltongue

回答

1

考慮轉彎for環成lapply用於dataframes(等於rand_sample的行的列表,然後運行對列表do.call(rbind, ...)成一個單一的數據幀和最後cbindrand_sampletransform在端是去除不需要的現在時間

dfList <- lapply(rand_sample$times, function(current) { 

    mW <- abs(diff(current[[1]]$white)) 
    mB <- abs(diff(current[[1]]$black)) 

    data.frame(
    maxWhite = max(mW), 
    minWhite = min(mW), 
    maxBlack = max(mB), 
    minBlack = min(mB), 
    sdWhite = sd(mW), 
    sdBlack = sd(mB), 
    avgW = mean(mW), 
    avgB = mean(mB) 
) 
}) 

all_times <- do.call(rbind, dfList) 

finaldf <- transform(cbind(rand_sample, all_times), times=NULL) 

採樣輸入

rand_sample <- data.frame(
    ID = vapply(seq(50), function(i) sample(seq(15), 1, replace=TRUE), integer(1)), 
    GROUP = vapply(seq(50), function(i) sample(LETTERS, 1, replace=TRUE), character(1)) 
) 

rand_sample$times <- lapply(1:50, function(i) 
          list(data.frame(white=sample(1000:2000, 50), 
              black=sample(1000:2000, 50)))) 

輸出

head(finaldf) 

# ID GROUP maxWhite minWhite maxBlack minBlack sdWhite sdBlack  avgW  avgB 
# 1 3  N  807  3  778  32 212.5353 177.5051 327.4082 297.3469 
# 2 12  Q  858  2  892  7 261.3543 222.4173 356.1837 366.7143 
# 3 6  R  749  13  910  8 208.5439 233.3391 324.6735 348.2041 
# 4 5  V  892  8  886  20 246.3769 261.3922 356.7347 329.5306 
# 5 4  O  842  5  886  2 200.1235 257.9464 350.2653 300.7347 
# 6 3  T  790  17  908  53 204.7842 235.0276 319.7959 385.1224 
+0

哇。這簡直太不可思議了。你救了我這麼頭痛。爲什麼lapply比for循環快得多?我認爲他們基本上是相同的運行時間。 – Parseltongue

+0

太棒了!樂意效勞。兩者都是循環,但在這裏我們運行批量操作而不是逐行操作。 – Parfait