簡體   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