簡體   English   中英

在 R 中使用 for 循環在管道上迭代變量

[英]Iterating variables over a pipeline with for loop in R

我有一個如下簡化的數據集:

x_1 <- c(1, NA, 2, 3, NA, 4, 5)
x_2 <- c(2, 1, NA, NA, NA, 4, 6)
y_1 <- c(2, 4, 6, 8, NA, 10, NA)
y_2 <- c(NA, 4, NA, 8, 10, 11, 13)
df <- data.frame(x_1, x_2, y_1, y_2)

  x_1 x_2 y_1 y_2
1   1   2   2  NA
2  NA   1   4   4
3   2  NA   6  NA
4   3  NA   8   8
5  NA  NA  NA  10
6   4   4  10  11
7   5   6  NA  13

目標是合並兩個對應變量(x 和 y)中的每一個,並用 NA 替換不相同的值(例如 x_1 和 x_2 的第一行)。 我用以下方法做到了這一點:

df <- df %>%
  mutate(x = coalesce(x_1, x_2)) %>%
  mutate(x = ifelse(!is.na(x) &
                    !is.na(x_2) &
                    x != x_2,
                    NA,
                    x)) %>%
 select(!c(x_1, x_2))

現在,我必須使用 21 個變量來執行此操作,所以我認為我將變量放在一個列表中,並使用這樣的 for 循環通過管道將它們提供給它們:

cols <- c("x", "y")

for(i in cols){
  var_1 <- paste(i, "1", sep = "_")
  var_2 <- paste(i, "2", sep = "_")
  
  df <- df %>%
    mutate(i = coalesce(var_1, var_2)) %>%
    mutate(i = ifelse(!is.na(i) &
                      !is.na(var_2) &
                      i != var_2,
                      NA,
                      i)) %>%
    select(!c(var_1, var_2))
}

發生的情況是代碼被執行,但沒有新變量,只有變量“i”具有空值。 似乎 R 無法將管道中的“i”識別為迭代器,但它確實識別了“var_1”和“var_2”(因為它們已從數據集中刪除)。

有誰知道這是為什么以及我該如何解決?

提前非常感謝。

fun <- function(x, var) {

  var_1 <- sym(paste(var, "1", sep = "_"))
  var_2 <- sym(paste(var, "2", sep = "_"))

  x %>%
    mutate(!!var := ifelse((!!var_1 != !!var_2) %in% TRUE,
                           NA, coalesce(!!var_1, !!var_2))) %>%
    select(!c(var_1, var_2))
}

cols <- c("x", "y")

Reduce(fun, cols, init = df)

#    x  y
# 1 NA  2
# 2  1  4
# 3  2  6
# 4  3  8
# 5 NA 10
# 6  4 NA
# 7 NA 13

如果你想避免 rlang:

library(tidyverse)
library(stringr)

x_1 <- c(1, NA, 2, 3, NA, 4, 5)
x_2 <- c(2, 1, NA, NA, NA, 4, 6)
y_1 <- c(2, 4, 6, 8, NA, 10, NA)
y_2 <- c(NA, 4, NA, 8, 10, 11, 13)
df <- data.frame(x_1, x_2, y_1, y_2)

my_coalesce <- function(d) {
  vec_1 <- select(d, 1) %>% pull()
  vec_2 <- select(d, 2) %>% pull()
  res <- coalesce(vec_1, vec_2)
  res[vec_1 != vec_2] <- NA
  res
}

cols <- c("x", "y")

map(cols, ~df %>%
      select(starts_with(.x)) %>% # or:
      #select(str_c(.x, "_", 1:2)) %>% 
      my_coalesce()) %>%
  set_names(cols) %>%
  as_tibble()

暫無
暫無

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

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