[英][R]: applying a function to columns based on conditional row position
我試圖在遇到該列的最大值后,在數據框中找到滿足某個條件的列的觀察數。
這是一個高度簡化的例子:
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
因此,假設在排除列中的所有觀察結果(包括列的最大值出現的行)之后,我試圖找到每列大於5的觀察數。
預期結果:
samp1 samp2 samp3 samp4
2 2 4 3
通過使用嵌套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)
}}
這將創建一個新的數據框,我可以在其上運行簡單的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
對於這個微小的示例數據集來說,這一切都很好,但是對於接近我的真實數據集大小的任何東西來說都非常慢。 哪個大(2000 x 2000或更大)和眾多。 我用我的一個文件的截斷版本(較少的列,但行數相同)嘗試了它並且它運行了至少5個小時(當我離開工作時我離開了它)。 此外,除了能夠運行apply函數之外,我並不需要新的數據幀。
有沒有辦法更有效地做到這一點? 我嘗試使用seq
和max的行號來限制apply
函數的行。
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)})
這將啟動此警告消息的四個實例:
1: In seq(1, nrow(fake.dat)) == (maxrow) :
longer object length is not a multiple of shorter object length
如果我忽略警告信息並獲得輸出,它不會給我我預期的答案:
samp1 samp2 samp3 samp4
2 3 3 3
我也試過使用while
函數來保持循環,所以我停止了它(我放錯了我為此嘗試的代碼)。
到目前為止,最有希望的結果來自嵌套的for loops
,但我知道它非常低效,我希望有更好的方法。 我還是R的新手,我確定我在某處搗亂某些語法。 提前感謝您提供的任何幫助!
這是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
如果您需要它作為兩個步驟:
datNA <- fake.dat %>%
mutate_each(funs(replace(., seq_len(which.max(.)), NA)))
datNA %>%
summarise_each(funs(sum(.>5, na.rm=TRUE)))
這是使用data.table
的一種方法:
library(data.table)
##
data <- 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))
##
Dt <- data.table(data)
##
R> Dt[,lapply(.SD,function(x){
y <- x[(which.max(x)+1):.N]
length(y[y>5])
})
samp1 samp2 samp3 samp4
1: 2 2 4 3
base
R中的單線程:
vapply(fake.dat,function(x) sum(x[(which.max(x)+1):length(x)]>5),1L)
#samp1 samp2 samp3 samp4
# 2 2 4 3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.