【问题标题】:How to calculate cumsum based on row names stored as a list?如何根据存储为列表的行名计算 cumsum?
【发布时间】:2016-08-23 19:11:50
【问题描述】:

我有一个大数据框,第一列是字母数字行名。我使用下面的 idx 为每列随机选择行(这里是 3 行)。我现在需要计算每个 idx[i,j] 的累积和。我的数据框很大,所以为了计算时间,首选 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)

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

谢谢

【问题讨论】:

  • “我的数据框很大,所以为了计算时间,首选 plyr 包中的函数” - 这没有意义。您使用 plyr 是因为它的简单性和易用性,而不是因为它速度快或可扩展到大型数据集。

标签: r dataframe 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

【讨论】:

  • 感谢@Jav 投入时间和精力。我认为我不应该将 idx 转换为向量,因为我需要 idx 具有二维。您可能会注意到相同的行名称在不同的列中具有不同的值,因此最终输出假设在单独的列中具有每列的累积总和。在此示例中,一列包含 ('t54' , 't54'+'t23' , t54'+'t23' +'t13') 对于 V2 和另一列包含 ("t14", "t14"+ V3 列的 "t13" 、 "t14"+"t13"+"t54")。
  • 抱歉,我主要更正了最后一行代码以反映累积和。我还留下了 idx 作为列表。让我知道上面的输出是否符合您的预期。
  • 另外,如果需要对更多列进行概括,请告诉我,我可以相应地编辑以上内容。
  • 我认为 V1 不应该出现在最终输出中,因为 idx 可能会为每列选择 3 个不同的行。鉴于上述示例的输出应该是单个数据帧,V2 为 (5.4 , 10.7, 16.7),V3 为 (5.1, 11.2, 13.6)。
  • "data.table 解决方案可能和plyr" 一样快(也许更快),哈哈,是的。 data.table 可能和 plyr 一样快,就像碳纤维赛车可能和 big wheel 一样快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-11
相关资源
最近更新 更多