我们说我现在有一个包含两列的数据框:
df<- data.frame(scores_set1=c(32,45,65,96,45,23,23,14),
scores_set2=c(32,40,60,98,21,23,21,63))
我想随机选择一些行
selected_indeces<- sample(c(1:8), 4, replace = FALSE)
现在我想依次添加selected_indeces
的值,这意味着对于第一个selected_indeces
我只需要该特定行的值,对于第二个我想要第二行值+第一个选择的value ...对于第n个索引,我想要已经选择的所有值的总和+第n行的值。所以,首先需要一个矩阵来将结果放入
cumulative_loss<-matrix(rep(NA,8*2),nrow=8,ncol=2)
然后每个列一个循环,每个selected_index
另一个循环for (s in 1:ncol(df)) #for each column
{
for (i in 1:length(selected_indeces)) #for each randomly selected index
{
if (i==1)
{
cumulative_loss[i,s]<- df[selected_indeces[i],s]
}
if (i > 1)
{
cumulative_loss[i,s]<- df[selected_indeces[i],s] +
df[selected_indeces[i-1],s]
}
}
}
虽然这可能是一种天真的方式来做这样的事情,但事情是,如果(i = 4)只添加第4和第3选择的值,而我希望它添加第一,第二,第三和第四随机选择和把它返还。
答案 0 :(得分:3)
方便地,cumsum()
直接处理data.frames,在这种情况下,它独立地在每个列上运行。因此,我们可以使用索引操作索引所选的df
行,并将结果直接传递给cumsum()
以获得所需的输出:
set.seed(0L);
sel <- sample(1:8,4L);
sel;
## [1] 8 2 3 6
df[sel,];
## scores_set1 scores_set2
## 8 14 63
## 2 45 40
## 3 65 60
## 6 23 23
cumsum(df[sel,]);
## scores_set1 scores_set2
## 8 14 63
## 2 59 103
## 3 124 163
## 6 147 186
要为每列选择不同的索引,我们可以使用apply()
:
set.seed(0L);
apply(df,2L,function(col) cumsum(col[sample(1:8,4L)]));
## scores_set1 scores_set2
## [1,] 14 63
## [2,] 59 103
## [3,] 124 126
## [4,] 147 147
如果你想提前计算索引,它会变得有点棘手。这是一种方法:
set.seed(0L);
sels <- replicate(2L,sample(1:8,4L)); sels;
## [,1] [,2]
## [1,] 8 8
## [2,] 2 2
## [3,] 3 6
## [4,] 6 5
sapply(seq_len(ncol(df)),function(ci) cumsum(df[[ci]][sels[,ci]]));
## [,1] [,2]
## [1,] 14 63
## [2,] 59 103
## [3,] 124 126
## [4,] 147 147
答案 1 :(得分:2)
以下是使用data.table
执行此操作的方法(考虑到您对@ bgoldst&#39的回答的评论:
library(data.table); setDT(df)
#sample 4 elements of each column (i.e., every element of .SD), then cumsum them
df[ , lapply(.SD, function(x) cumsum(sample(x, 4)))]
如果你想为每一列使用不同的索引,我会先预先选择它们:
set.seed(1023)
idx <- lapply(integer(ncol(df)), function(...) sample(nrow(df), 4))
idx
# [[1]] #indices for column 1
# [1] 2 8 6 3
#
# [[2]] #indices for column 2
# [1] 4 8 5 1
然后稍微修改上面的内容:
df[ , lapply( seq_along(.SD), function(jj) cumsum(.SD[[jj]][ idx[[jj]] ]) )]
这是我用代码功能编写的括号/圆括号中最疯狂的汇编,所以我觉得有点理解它是有道理的:
seq_along
.SD
选出每列的索引编号,jj
.SD[[jj]]
选择j
列,idx[[jj]]
选择该列的索引,.SD[jj]][idx[jj]]]
选择idx[[jj]]
行j
行第二列;这相当于.SD[idx[jj], jj, with = FALSE]
cumsum
我们为列length(idx[[jj]])
选择了jj
行。结果:
# V1 V2
# 1: 45 98
# 2: 59 161
# 3: 82 182
# 4: 147 214