У меня есть data.frame
, который выглядит вот так.
df <-
tibble::tribble(
~name, ~age, ~birthday, ~address, ~favorite_fruit,
'josh', '26', '1998-04-14', '1 main st', 'banana',
'jason', '2000-09-01', '2 front st', 'apple', NA,
'nate', '1992-dec-25', '3 oak st', 'blueberry', NA
)
df
#> # A tibble: 3 x 5
#> name age birthday address favorite_fruit
#> <chr> <chr> <chr> <chr> <chr>
#> 1 josh 26 1998-04-14 1 main st banana
#> 2 jason 2000-09-01 2 front st apple <NA>
#> 3 nate 1992-dec-25 3 oak st blueberry <NA>
Как вы могли заметить, данные о возрасте собирались не для всех людей (не считая того, что я мог их вычислить по birthday
). Поэтому все значения в некоторых строках после столбца name
неправильно сдвинуты влево на один столбец. Мой идеальный результат — это NA
в столбце age
и правильные значения во всех остальных столбцах. Как я могу этого добиться? Если возможно, предпочтительнее решение tidyverse.
Наверное, ты можешь попробовать это
idx <- is.na(df$favorite_fruit)
df[idx, -(1:2)] <- df[idx, -c(1, length(df))]
df$age[idx] <- NA
что дает
> df
# A tibble: 3 × 5
name age birthday address favorite_fruit
<chr> <chr> <chr> <chr> <chr>
1 josh 26 1998-04-14 1 main st banana
2 jason NA 2000-09-01 2 front st apple
3 nate NA 1992-dec-25 3 oak st blueberry
1) Отдельно обвязать ряды с НА в favorite_fruit
и остальные ряды, а затем связать их вместе.
library(dplyr)
df1 <- df %>%
filter(is.na(favorite_fruit)) %>%
mutate(favorite_fruit = address, address = birthday, birthday = age, age = NA)
df2 <- df %>%
filter(!is.na(favorite_fruit))
bind_rows(df1, df2)
предоставление
# A tibble: 3 × 5
name age birthday address favorite_fruit
<chr> <chr> <chr> <chr> <chr>
1 jason <NA> 2000-09-01 2 front st apple
2 nate <NA> 1992-dec-25 3 oak st blueberry
3 josh 26 1998-04-14 1 main st banana
2) mutate_cond Функция mutate_cond
— это трехстрочная функция, определенная по этой ссылке . Это похоже на mutate
, за исключением того, что у него есть второй аргумент, так что mutate
применяется только к тем строкам, для которых этот аргумент верен.
df %>%
mutate_cond(is.na(favorite_fruit),
favorite_fruit = address, address = birthday, birthday = age, age = NA)
Вы можете использовать shift_row_values()
из пакета hacksaw
:
library(hacksaw)
library(dplyr)
bind_cols(select(df, name),
select(df, -name) |>
shift_row_values(.dir = "right", at = is.na(df$favorite_fruit)))
# name age birthday address favorite_fruit
# <chr> <chr> <chr> <chr> <chr>
# 1 josh 26 1998-04-14 1 main st banana
# 2 jason NA 2000-09-01 2 front st apple
# 3 nate NA 1992-dec-25 3 oak st blueberry