[R]:根据条件行位置将函数应用于列

NMc*_*NMc 4 for-loop r apply conditional-statements

我试图在遇到该列的最大值后,在数据框中找到满足某个条件的列的观察数.

这是一个高度简化的例子:

fake.dat<-data.frame(samp1=c(5,6,7,5,4,5,10,5,6,7), samp2=c(2,3,4,6,7,9,2,3,7,8), samp3=c(2,3,4,11,7,9,2,3,7,8),samp4=c(5,6,7,5,4,12,10,5,6,7))

       samp1 samp2 samp3 samp4
1      5     2     2     5
2      6     3     3     6
3      7     4     4     7
4      5     6    11     5
5      4     7     7     4
6      5     9     9    12
7     10     2     2    10
8      5     3     3     5
9      6     7     7     6
10     7     8     8     7
Run Code Online (Sandbox Code Playgroud)

因此,假设在排除列中的所有观察结果(包括列的最大值出现的行)之后,我试图找到每列大于5的观察数.

预期结果:

samp1 samp2 samp3 samp4 
   2     2     4    3 
Run Code Online (Sandbox Code Playgroud)

通过使用嵌套for loops来排除我不想要的观察,我能够得到我想要的答案.

newfake.dat<-data.frame()

for(j in 1:length(fake.dat)){
for(i in 1:nrow(fake.dat)){
    ifelse(i>max.row[j],newfake.dat[i,j]<-fake.dat[i,j],"NA")
print(newfake.dat)
}}
Run Code Online (Sandbox Code Playgroud)

这创建了一个新的数据框,我可以在其上运行一个简单的apply功能.

colcount<-apply(newfake.dat,2,function(x) (sum(x>5,na.rm=TRUE)))

   V1 V2 V3 V4
1  NA NA NA NA
2  NA NA NA NA
3  NA NA NA NA
4  NA NA NA NA
5  NA NA  7 NA
6  NA NA  9 NA
7  NA  2  2 10
8   5  3  3  5
9   6  7  7  6
10  7  8  8  7

V1 V2 V3 V4 
 2  2  4  3 
Run Code Online (Sandbox Code Playgroud)

对于这个微小的示例数据集来说,这一切都很好,但是对于接近我的真实数据集大小的任何东西来说都非常慢.哪个大(2000 x 2000或更大)和众多.我用我的一个文件的截断版本(较少的列,但行数相同)尝试了它并且它运行了至少5个小时(当我离开工作时我离开了它).此外,除了能够运行apply函数之外,我并不需要新的数据帧.

有没有办法更有效地做到这一点?我试着apply通过使用seq和最大行号来限制函数的行.

maxrow<-apply(fake.dat,2,function(x) which.max(x))
print(maxrow)

seq.att<-apply(fake.dat,2,function(x) {
    sum(x[which(seq(1,nrow(fake.dat))==(maxrow)):nrow(fake.dat)]>5,na.rm=TRUE)})
Run Code Online (Sandbox Code Playgroud)

这将启动此警告消息的四个实例:

1: In seq(1, nrow(fake.dat)) == (maxrow) :
  longer object length is not a multiple of shorter object length
Run Code Online (Sandbox Code Playgroud)

如果我忽略警告信息并获得输出,它不会给我我预期的答案:

samp1 samp2 samp3 samp4 
    2     3     3     3 
Run Code Online (Sandbox Code Playgroud)

我也试过使用一个while循环的功能,所以我停止了它(我放错了我为此尝试的代码).

到目前为止,最有希望的结果来自嵌套for loops,但我知道它非常低效,我希望有更好的方法.我还是R的新手,我确定我在某处捣乱某些语法.提前感谢您提供的任何帮助!

akr*_*run 5

这是一种dplyr复制您显示的相同过程的方法base R

library(dplyr)
fake.dat %>% 
        summarise_each(funs(sum(.[(which.max(.)+1):n()]>5,
                na.rm=TRUE)))
#   samp1 samp2 samp3 samp4
#1     2     2     4     3
Run Code Online (Sandbox Code Playgroud)

如果您需要它作为两个步骤:

datNA <- fake.dat %>% 
               mutate_each(funs(replace(., seq_len(which.max(.)), NA)))

datNA %>% 
      summarise_each(funs(sum(.>5, na.rm=TRUE)))
Run Code Online (Sandbox Code Playgroud)