[英]Vectorizing a loop through lines of data frame R while accessing multiple variables the dataframe
還有另一個apply
問題。
我已經閱讀了很多有關R中的apply
函數族的文檔(並且在我的工作中經常使用它們)。 我定義了一個函數myfun
,我想在該函數下應用到dataframe inc
每一行。 我想我需要一段時間的apply(inc,1,myfun)
變體,但仍然無法完全解決。 我已經包含了一個循環,該循環可以完全實現我想做的事情……它對我的真實數據而言非常慢且效率低下,它比我在此處包含的樣本數據大得多。
我希望這是一個快速解決方案,但是我不能完全動手做……也許有一些特殊論點...
可以適用嗎?
下列代碼的英文版本:我想查看inc
數據chg$Submit.Date
所有Submit Dates,並針對每個日期查找chg
有多少行,其中chg$Submit.Date
在inc$Submit.Date
某個范圍內inc$Submit.Date
。 范圍由myfun
fdays
和bdays
控制
chgdf <- data.frame(Submit.Date=as.Date(c("2013-09-27", "2013-09-4", "2013-08-01", "2013-06-24", '2013-05-29', '2013-08-20')), ID=c('001', '001', '001', '001', '001', '005'), stringsAsFactors=F)
incdf <- data.frame(Submit.Date=as.Date(c("2013-10-19", "2013-09-14", "2013-08-22", '2013-08-20')), ID=c('001', '001', '002', '006'), stringsAsFactors=F)
myfun <- function(tdate, aid, chg=chgdf, inc=incdf, fdays=30, bdays=30) {
fdays <- tdate+fdays
bdays <- tdate-bdays
chg2 <- chg[chg$ID==aid & chg$Submit.Date<fdays & chg$Submit.Date>bdays, ]
ret <- nrow(chg2)
return(ret)
}
tdate <- inc[inc$ID==aid, 'Submit.Date'][1]
myfun(tdate, aid='001', bdays=50, fdays=100)
inc$chgw <- 0
for(i in 1:nrow(inc)){
aid <- inc$ID[i]
tdate <- inc$Submit.Date[i]
inc$chgw[i] <- myfun(tdate, aid, bdays=50, fdays=100)
}
類似於朱利安的答案:
sapply(
split(incdf, 1:nrow(incdf)),
function(x) do.call(myfun, c(unname(x), bdays=50, fdays=100))
)
這里我不使用apply
因為apply
會將整個行強制轉換為同一類型,這可能不是所希望的。 請注意,我們需要unname(x)
因為您的df與函數的args沒有相同的列名。
首先,在調用apply
所有值都被強制轉換為字符串,因此您需要在使用tdate
之前對其進行轉換。 否則,您嘗試將天數添加到字符串中:
tdate <- as.Date(tdate)
fdays <- tdate+fdays
bdays <- tdate-bdays
其次,您調用apply(inc, 1, myfun)
。 請注意,在這種情況下,您要將單個參數傳遞給myfun
(整行),而不是myfun
應該接收的多個參數。
解決方案1:更改您的函數以接收整個數據幀並按您的方式進行調用:
myfun <- function(row, chg=chgdf, inc=incdf, fdays=30, bdays=30) {
tdate <- as.Date(row[1])
fdays <- tdate+fdays
bdays <- tdate-bdays
chgdf2 <- chgdf[chgdf$ID==row[2] & chgdf$Submit.Date<fdays & chgdf$Submit.Date>bdays, ]
ret <- nrow(chgdf2)
return(ret)
}
> apply(inc, 1, myfun)
[1] 1 2 0 0
解決方案2:使用函數調用中的所有參數調用apply
:
myfun <- function(tdate, aid, chg=chgdf, inc=incdf, fdays=30, bdays=30) {
fdays <- tdate+fdays
bdays <- tdate-bdays
chgdf2 <- chgdf[chgdf$ID==aid & chgdf$Submit.Date<fdays & chgdf$Submit.Date>bdays, ]
ret <- nrow(chgdf2)
return(ret)
}
> apply(inc, 1, function(row) myfun(as.Date(row[1]), row[2]))
[1] 1 2 0 0
我個人更喜歡第二種解決方案,因為它使您可以更改myfun
其他參數的默認值:
> apply(inc, 1, function(row) myfun(as.Date(row[1]), row[2], bdays=50, fdays=50))
[1] 2 3 0 0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.