删除R循环中的列

时间:2018-03-08 03:23:55

标签: r

我有一个数据框,我想要替换变量

    如果age1_corr_1不是NA ,则
  • age_1,其值为变量age1_corr_1 如果age1_corr_2不是NA,则
  • age_2,其值为变量age1_corr_2,...,
  • 如果age1_corr_n不是NA,则
  • age_n,其值为变量age1_corr_n。

然后我想删除变量age1_corr_1,age1_corr_2,...,age1_corr_n。我已经弄清楚如何在循环中完成第一部分(更改值),但无法弄清楚如何删除变量。有什么建议吗?

示例数据

y <- data.frame("age_1" = c(5,1,1,10), "age1_corr_1" = c(1,NA,NA,0), "age_2" = c(1,2,3,4), "age1_corr_2" = c(NA, NA, 10, 9),
            "age_3" = c(4,3,2,5), "age1_corr_3" = c(NA,NA,NA,6), "age_4" = c(1,4,2,7), "age1_corr_4" = c(NA, NA, NA,NA))

将根据age1_corr_n

更改age_n值的代码
for(i in 1:4){
  cname1 <- paste0("age_",i)
  cname2 <- paste0("age1_corr_",i)
  y[,cname1] <- ifelse(!is.na(y[,cname2]), y[,cname2], y[,cname1])
}

我想要的输出是

  age_1 age_2 age_3 age_4
1     1     1     4     1
2     1     2     3     4
3     1    10     2     2
4     0     9     6     7       

3 个答案:

答案 0 :(得分:1)

如果要删除的列有一个模式(或者相反,您要保留的模式),则有几个选项。

以下是您提供的数据:

y <- data.frame("age_1" = c(5,1,1,10), "age1_corr_1" = c(1,NA,NA,0), "age_2" = c(1,2,3,4), "age1_corr_2" = c(NA, NA, 10, 9),
            "age_3" = c(4,3,2,5), "age1_corr_3" = c(NA,NA,NA,6), "age_4" = c(1,4,2,7), "age1_corr_4" = c(NA, NA, NA,NA))

这是一个dplyr示例,说明如何仅获取遵循模式age_N的列,其中N为1,2,3或4:

library(dplyr)
x <- select(y, paste("age", 1:4, sep = "_"))

或者,您可以选择您不想要的列的模式:

x <- select(y, -grep("_corr_", current_vars()))

这使用以下策略: *您可以通过首先添加减号来选择一列或一组列。 * current_vars()是dplyr中的辅助函数,它计算数据的所有变量名称(此处为y)

答案 1 :(得分:1)

使用dplyr::coalesce()进行实际工作(描述:“给定一组向量,coalesce()在每个位置找到第一个非缺失值。”)。然后使用dplyr::select()删除列,在您不再需要的列前面使用负号。

library(magrittr)
y %>% 
  dplyr::mutate(
    age1_corr_4     = as.numeric(age1_corr_4), # Delete this line if it's already a numeric/floating data type.
    age_1           = dplyr::coalesce(age1_corr_1, age_1),
    age_2           = dplyr::coalesce(age1_corr_2, age_2),
    age_3           = dplyr::coalesce(age1_corr_3, age_3),
    age_4           = dplyr::coalesce(age1_corr_4, age_4)
  ) %>% 
  dplyr::select(
    -age1_corr_1, -age1_corr_2, -age1_corr_3, -age1_corr_4
  )

可生产

  age_1 age_2 age_3 age_4
1     1     1     4     1
2     1     2     3     4
3     1    10     2     2
4     0     9     6     7

编辑:我道歉,我专注于任务的合并部分,并忽略了任务的 n 部分。

答案 2 :(得分:0)

以下是另外两种可以处理任意数量列的方法。对于此特定示例数据集,请确保第4列正确表示为具有y$age1_corr_4 <- as.numeric(y$age1_corr_4))的浮点数。

就像Dan Hall的回应一样,一种方法可以保留你想要的列......

library(magrittr)
coalesce_corr1 <- function( index ) {
  name_age  <- paste0("age_"      , index)
  name_corr <- paste0("age1_corr_", index)
  y %>%
    dplyr::mutate(
      !!name_age   := dplyr::coalesce(.data[[name_corr]], .data[[name_age]])
    ) %>%
    dplyr::select(!!name_age)
}

1:4 %>% 
  purrr::map(coalesce_corr) %>% 
  dplyr::bind_cols()

...而另一个则删除了你不想要的列。

z <- y
coalesce_corr2 <- function( index ) {
  name_age  <- paste0( "age_"      , index)
  name_corr <- paste0( "age1_corr_", index)

  z <<- z %>%
    dplyr::mutate(
      !!name_age   := dplyr::coalesce(.data[[!!name_corr]], .data[[!!name_age]])
    )
  z[[name_corr]] <<- NULL
}

1:4 %>% 
  purrr::walk(coalesce_corr2)
z

我希望最后一个不需要全局变量(使用<<-),因此,我实际上推荐Dan的方法,但我想尝试quosures for output variables