2016-08-26 84 views
1

我想將管(鏈)magrittr對象放入循環中。我怎樣才能做到這一點?
我將使用空操作/數據爲例:優化R鏈(magrittr)

library(data.table) 
library(magrittr) 

# Dummy data modification 
d <- mtcars %>% 
    setDT() %>% 
    .[, cylSQ := sqrt(cyl)] %>% 
    .[, carb3 := carb^3] 
# Dummy loop 
res <- list() 
for(i in unique(d$gear)) { 
    res[[i]] <- d[gear == i] %>% 
     .[, lm(cylSQ ~ mpg + carb3 * wt)] %>% 
     .$fitted.values 
} 

是否有可能不創建對象d和管直接循環?例如:

for(i in unique(.$gear)) { 
    res[[i]] <- .[gear == i] %>% 
    ... 
} 

編輯:我不想data.tabledplyr更換循環,只是好奇管道。

+1

我可能是錯的,是不是有'purrr'包的原因? – zx8754

+0

@ zx8754我以前沒有聽說過它,不知道這是我在找什麼,但仍然看起來非常好,值得一看。感謝您的好建議! – PoGibas

+1

'mtcars%>%setDT'違背了不修改輸入的dplyr語法/哲學fyi。 – Frank

回答

2

這是一個粗略的解決方法,但您可以使用magrittr%$%中的說明運算符。

即:

mtcars %>% 
    filter(hp > 1) %$% 
    for(i in 1:ncol(.)) { 
    print(.[1,i]) 
    } 

[1] 21 
[1] 6 
[1] 160 
[1] 110 
[1] 3.9 
[1] 2.62 
[1] 16.46 
[1] 0 
[1] 1 
[1] 4 
[1] 4 
1

我不magrittr從業所以它很可能得到改善,但至少工作,並且應該是有效的。

as.data.table(mtcars 
      )[, cylSQ := sqrt(cyl) 
       ][, carb3 := carb^3 
        ][, lm(cylSQ ~ mpg + carb3 * wt)$fitted.values, by=gear 
        ] %>% 
    split(by = "gear", keep.by = FALSE) %>% 
    lapply(unlist) %>% 
    lapply(unname) -> res 

由於新split.data.table它要求在1.9.7 data.table,見installation wiki,以詳細瞭解安裝在各種平臺上。

3

難道你不介意在這裏使用dplyr而不是data.table?如果沒有,試試這個:

library(dplyr) 
d <- mtcars %>% 
    mutate(cylSQ = sqrt(cyl), carb3 = carb^3) %>% 
    group_by(gear) %>% 
    do(fitted.values = lm(cylSQ ~ mpg + carb3 * wt, data = .)[["fitted.values"]]) 
+0

看起來非常好。 – PoGibas