繁体   English   中英

如何根据 R 中 tibble 中另一列指示的列的值添加列

[英]How to add a column based on values of columns indicated by another column in a tibble in R

在下面的示例中,我想根据列“变量”的值(即 1 和 20)添加列“值”。

toy_data <-
  tibble::tribble(
    ~x, ~y, ~variable,
    1,  2,  "x",
    10, 20, "y"
  )

像这样:

X 是的 多变的 价值
1 2 X 1
10 20 是的 20

但是,以下方法均无效:

toy_data %>%
  dplyr::mutate(
    value = get(variable)
  )

toy_data %>%
  dplyr::mutate(
    value = mget(variable)
  )

toy_data %>%
  dplyr::mutate(
    value = mget(variable, inherits = TRUE)
  )

toy_data %>%
  dplyr::mutate(
    value = !!variable
  )

我怎样才能做到这一点?

这里有一些应该可以很好地扩展的选项。

首先是一个基本选项,它同时适用于variable列及其索引。 (我制作了数据框的副本,只是为了让原始数据保持完整,以便进行更多编程。)

library(dplyr)

toy2 <- toy_data
toy2$value <- mapply(function(v, i) toy_data[[v]][i], toy_data$variable, seq_along(toy_data$variable))
toy2
#> # A tibble: 2 × 4
#>       x     y variable value
#>   <dbl> <dbl> <chr>    <dbl>
#> 1     1     2 x            1
#> 2    10    20 y           20

其次使用purrr::imap_dbl沿变量及其索引进行迭代并返回一个双精度值。

toy_data %>%
  mutate(value = purrr::imap_dbl(variable, function(v, i) toy_data[[v]][i]))
#> # A tibble: 2 × 4
#>       x     y variable value
#>   <dbl> <dbl> <chr>    <dbl>
#> 1     1     2 x            1
#> 2    10    20 y           20

第三是最不直接的,但我个人最有可能使用它,也许只是因为它是一个适合我的许多工作流程的过程。 透视生成数据的长版本,让您看到variable的值以及xy的对应值,然后您可以过滤这 2 列匹配的位置。 然后自连接回数据框。

inner_join(
  toy_data,
  toy_data %>%
    tidyr::pivot_longer(cols = -variable, values_to = "value") %>%
    filter(variable == name),
  by = "variable"
) %>%
  select(-name)
#> # A tibble: 2 × 4
#>       x     y variable value
#>   <dbl> <dbl> <chr>    <dbl>
#> 1     1     2 x            1
#> 2    10    20 y           20

编辑: @jpiversen 正确地指出,如果variable有重复项,则自联接将不起作用——在这种情况下,将行号添加到数据中并将其用作附加的联接列。 这里我先添加一个额外的观察来说明。

toy3 <- toy_data %>%
  add_row(x = 5, y = 4, variable = "x") %>%
  tibble::rowid_to_column()
inner_join(
  toy3,
  toy3 %>%
    pivot_longer(cols = c(-rowid, -variable), values_to = "value") %>%
    filter(variable == name),
  by = c("rowid", "variable")
) %>%
  select(-name, -rowid)

如果您事先知道 dataframe 中有哪些变量:使用ifelse()dplyr::case_when()类的简单逻辑在它们之间进行选择。

如果不是:使用函数式编程。 下面是一个例子:

library(dplyr)

f <- function(data, variable_col) {
  
  data[[variable_col]] %>% 
    purrr::imap_dbl(~ data[[.y, .x]])
  
}

toy_data$value <- f(toy_data, "variable")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM