簡體   English   中英

根據輸入為 dataframe 的另一列替換列的值

[英]Replace values of a column based on another column having as input a dataframe

使用base::replace function 我想根據列y的值更改列z的一些值

library(tidyverse)

(df <- tibble(y = 10:13, z = 20:23))
#> # A tibble: 4 x 2
#>       y     z
#>   <int> <int>
#> 1    10    20
#> 2    11    21
#> 3    12    22
#> 4    13    23

我有data.frame val ,其中a列是用作條件的值, b列將是替換值。

(val <- tibble(a = c(10, 12), b = c(100, 200)))
#> # A tibble: 2 x 2
#>       a     b
#>   <dbl> <dbl>
#> 1    10   100
#> 2    12   200

使用以下方法可以獲得所需的結果,但僅當val中的所有值都在df中時才有效

df %>% mutate(z = replace(z, y %in% val$a, val$b))
#> # A tibble: 4 x 2
#>       y     z
#>   <int> <dbl>
#> 1    10   100
#> 2    11    21
#> 3    12   200
#> 4    13    23

例如,如果我將val更新為具有不在df中的值,則:

(val <- tibble(a = c(1, 10, 12), b = c(1, 100, 200)))
#> # A tibble: 3 x 2
#>       a     b
#>   <dbl> <dbl>
#> 1     1     1
#> 2    10   100
#> 3    12   200

我再次運行代碼......

df %>% mutate(z = replace(z, y %in% val$a, val$b))
#> Warning in x[list] <- values: number of items to replace is not a multiple of
#> replacement length
#> # A tibble: 4 x 2
#>       y     z
#>   <int> <dbl>
#> 1    10     1
#> 2    11    21
#> 3    12   100
#> 4    13    23

有錯誤...我該如何解決這個問題?

代表 package (v1.0.0) 於 2021 年 2 月 19 日創建

一種可能是:

df %>%
 mutate(z = coalesce(b[match(y, a)], z))

      y     z
  <int> <dbl>
1    10   100
2    11   200
3    12    22

我們不需要任何map ,因為“a”、“b”和“df”的行數具有相同的長度。 因此,可以使用==進行元素比較。 而不是replace ,使用ifelse/case_when等可能會更好,因為replace values應該與list條件 TRUE 元素的長度相同

library(dpyr)
df %>%
    mutate(z = case_when(a == y ~ as.integer(b), TRUE ~ z))

-輸出

# A tibble: 3 x 2
#      y     z
#  <int> <int>
#1    10   100
#2    11   200
#3    12    22

或使用base R

df$z <- with(df, ifelse(a == y, b, z))

在OP的代碼中,當我們這樣做時, length會有所不同

 replace(x = z, y == .x, values = .y)

其中 'z' 將是完整的列長度, .x.y將是每個行元素

更新

根據更新的數據,我們可以加入然后使用coalesce

df %>% 
    left_join(val, by = c('y' = 'a')) %>%
    transmute(y, z = coalesce(b, z))
# A tibble: 4 x 2
#      y     z
#  <dbl> <dbl>
#1    10   100
#2    11    21
#3    12   200
#4    13    23

replace的基本 R 選項

transform(
  df,
  z = replace(z, na.omit(match(y, a)), b[na.omit(match(y, a))])
)

   y   z
1 10 100
2 11 200
3 12  22

暫無
暫無

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

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