簡體   English   中英

dplyr/purrr 迭代列和行

[英]dplyr/purrr iterate over columns as well as rows

我試圖根據另一列中的值刪除(設置為 NA) 1 列中的值; 並在大量列上執行此操作。 這個想法是然后將數據傳遞給繪圖函數,為數據的不同切割生成不同的圖。

這是一個可重現的示例:

d <- data.frame("A_agree" = sample(1:7, 20, replace=T),
                "B_agree" = sample(1:7, 20, replace=T),
                "C_agree" = sample(1:7, 20, replace=T),
                "A_change" = sample(1:5, 20, replace=T),
                "B_change" = sample(1:5, 20, replace=T),
                "C_change" = sample(1:5, 20, replace=T))

我已經使用基本 R 找到了以下解決方案,但它當然很慢,而且我正在嘗試學習越來越多的dplyr ,所以想知道如何在dplyr實現這dplyr

d.positive <- d
for (n in (c("A","B","C"))) {
  for (i in 1:nrow(d.positive)) {
    d.positive[i, paste0(n, "_agree")] <- ifelse(d.positive[i, paste0(n, "_change")] > 3,
                                                 d.positive[i, paste0(n, "_agree")],
                                                 NA)
  }
}
d.neutral <- d
for (n in (c("A","B","C"))) {
  for (i in 1:nrow(d.neutral)) {
    d.neutral[i, paste0(n, "_agree")] <- ifelse(d.neutral[i, paste0(n, "_change")] == 3,
                                                 d.neutral[i, paste0(n, "_agree")],
                                                 NA)
  }
}
d.negative <- d
for (n in (c("A","B","C"))) {
  for (i in 1:nrow(d.negative)) {
    d.negative[i, paste0(n, "_agree")] <- ifelse(d.negative[i, paste0(n, "_change")] < 3,
                                                 d.negative[i, paste0(n, "_agree")],
                                                 NA)
  }
}

我以為我會使用gather() ,然后檢查每一行相應的列(因此!!dimension )是否大於某個值(在這種情況下為3 ),但它似乎不起作用?

d %>%
  gather(dimension,
         value,
         paste0(c("A","B","C"), "_agree")
         ) %>%
  case_when(!!dimension > 3 ~ value=NA)

或者,我認為我會使用map2_dfrpurrr ,但我認為它不會遍歷單元格,只需要整個列,因此這不起作用:

map2_dfr(.x = d %>%
                 select( paste0(c("A","B","C"), "_agree") ),
         .y = d %>%
                 select( paste0(c("A","B","C"), "_change") ),
         ~ if_else(.y > 3, x, NA)} )

任何指針都會非常有幫助,可以繼續了解dplyr的精彩世界!

我知道您想了解purrr ,但這里的基礎R更容易:

d.positive <- d  

check  <- d.positive[4:6] <= 3 #it's the same condition
d.positive[,1:3][check] <- NA

> d.positive
   A_agree B_agree C_agree A_change B_change C_change
1        1      NA      NA        4        3        2
2        2       2      NA        4        5        2
3        4      NA      NA        4        3        1
4        1      NA      NA        4        1        2
5       NA       1      NA        2        4        1
6       NA       7      NA        3        5        1
7       NA       6      NA        1        5        1
8       NA       6       4        2        5        5
9        4      NA      NA        4        1        2
10       1      NA      NA        5        1        2
11      NA      NA      NA        3        1        2
12      NA      NA      NA        1        3        3
13      NA      NA      NA        1        1        1
14      NA      NA      NA        3        2        3
15       1      NA      NA        5        3        3
16       2      NA      NA        4        3        2
17      NA      NA       6        1        1        4
18      NA      NA      NA        1        1        2
19      NA      NA      NA        2        3        1
20      NA      NA      NA        1        3        1

我建議將tidyr包與dplyr結合使用。 其中有新函數pivot_longerpivot_wider取代舊的gatherspread

結合使用這兩種解決方案可能如下:

d.neutral1 = 
  d %>% 
  mutate(row = row_number() ) %>% 
  pivot_longer(-row, names_sep = "_", names_to = c("name","type") ) %>% 
  pivot_wider(names_from = type, values_from = value) %>% 
  mutate(result = if_else(change == 3, agree, NA_integer_))

如果您想要與原始形狀相似的形狀

d.neutral1 %>% 
  select(-agree, -change) %>% 
  pivot_wider(names_from = name, values_from = result)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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