簡體   English   中英

通過數據幀R的行對循環進行矢量化處理,同時訪問數據幀的多個變量

[英]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.Dateinc$Submit.Date某個范圍內inc$Submit.Date 范圍由myfun fdaysbdays控制

設置一些虛假數據

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)
}

適用於一行inc數據幀

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM