#r #dplyr
Вопрос:
У меня есть набор данных, содержащий шаги, предпринятые потребителем на пути к совершению покупки, и значение, показывающее, сколько стоил каждый шаг. Я хочу избавиться от последнего значения в каждой строке, чтобы посмотреть, насколько помогли мои последние шаги. Мне нужна помощь в замене или уточнении этих значений.
Эти данные имеют разную длину и имеют множество различных значений:
My data looks somewhat like this.
df <- data.frame(
weight_1 = c(43L, 2L, 6L, 30L, 69L, 82L, 98L, 79L, 68L),
weight_2 = c(60L, 40L, 78L, 48L, 75L, 77L, 55L, 3L, 66L),
weight_3 = c(22L, 4L, 77L, 40L, 91L, 57L, 34L, 84L, NA),
weight_4 = c(88L, 47L, 77L, 82L, 31L, 19L, 11L, NA, NA),
weight_5 = c(80L, 65L, 12L, 17L, 62L, 95L, NA, NA, NA),
weight_6 = c(95L, 71L, 14L, 29L, 66L, 83L, NA, NA, NA),
weight_7 = c(64L, 20L, 69L, 57L, NA, NA, NA, NA, NA),
weight_8 = c(45L, 19L, NA, NA, NA, NA, NA, NA, NA)
)
Я нашел значение последней строки, используя
final_row <- as.data.frame(df[cbind( 1:nrow(df), max.col(!is.na(df),"last") )])
colnames(final_row)[1] <- "last_value"
Теперь я просто ищу способ удалить эти значения из набора данных, чтобы я мог просмотреть значения, не относящиеся к последнему шагу.
Комментарии:
1. Было бы полезно предоставить образец ваших данных, используя
dput()
их и делясь ими в рамках вашего вопроса, чтобы сделать их воспроизводимыми. Бесцеремонно я бы сказал, что вам нужно добавить переменную id , чтобы отслеживать использование респондентамиrow_number()
, затем преобразовать данные в длинный формат , используяpivot_longer()
изtidyr
пакета, затем удалитьNAs
сdrop_na()
, а затем отфильтровать любую строку с последним значениемfilter()
. Но опять же, было бы проще показать, как с реальными данными работать.
Ответ №1:
Возможно, вы этого хотите?
df <- data.frame(
weight_1 = c(43L, 2L, 6L, 30L, 69L, 82L, 98L, 79L, 68L),
weight_2 = c(60L, 40L, 78L, 48L, 75L, 77L, 55L, 3L, 66L),
weight_3 = c(22L, 4L, 77L, 40L, 91L, 57L, 34L, 84L, NA),
weight_4 = c(88L, 47L, 77L, 82L, 31L, NA, 19L, 11L, NA),
weight_5 = c(80L, 65L, 12L, 17L, 62L, NA, 40L, 95L, NA),
weight_6 = c(95L, 71L, 14L, NA, 29L, NA, 66L, 83L, NA),
weight_7 = c(64L, 20L, NA, NA, 69L, NA, 57L, NA, NA),
weight_8 = c(45L, NA, NA, NA, NA, NA, 19L, NA, NA)
)
library(dplyr, warn.conflicts = F)
df %>%
mutate(across(everything(), ~ifelse(cur_column() == names(df)[max.col(!is.na(df), ties.method = 'last')], NA, .)))
#> weight_1 weight_2 weight_3 weight_4 weight_5 weight_6 weight_7 weight_8
#> 1 43 60 22 88 80 95 64 NA
#> 2 2 40 4 47 65 71 NA NA
#> 3 6 78 77 77 12 NA NA NA
#> 4 30 48 40 82 NA NA NA NA
#> 5 69 75 91 31 62 29 NA NA
#> 6 82 77 NA NA NA NA NA NA
#> 7 98 55 34 19 40 66 57 NA
#> 8 79 3 84 11 95 NA NA NA
#> 9 68 NA NA NA NA NA NA NA
Создано 2021-07-19 пакетом reprex (v2.0.0)
более ранний ответ
df <- data.frame(
weight_1 = c(43L, 2L, 6L, 30L, 69L, 82L, 98L, 79L, 68L),
weight_2 = c(60L, 40L, 78L, 48L, 75L, 77L, 55L, 3L, 66L),
weight_3 = c(22L, 4L, 77L, 40L, 91L, 57L, 34L, 84L, NA),
weight_4 = c(88L, 47L, 77L, 82L, 31L, NA, 19L, 11L, NA),
weight_5 = c(80L, 65L, 12L, 17L, 62L, NA, 40L, 95L, NA),
weight_6 = c(95L, 71L, 14L, NA, 29L, NA, 66L, 83L, NA),
weight_7 = c(64L, 20L, NA, NA, 69L, NA, 57L, NA, NA),
weight_8 = c(45L, NA, NA, NA, NA, NA, 19L, NA, NA)
)
df
#> weight_1 weight_2 weight_3 weight_4 weight_5 weight_6 weight_7 weight_8
#> 1 43 60 22 88 80 95 64 45
#> 2 2 40 4 47 65 71 20 NA
#> 3 6 78 77 77 12 14 NA NA
#> 4 30 48 40 82 17 NA NA NA
#> 5 69 75 91 31 62 29 69 NA
#> 6 82 77 57 NA NA NA NA NA
#> 7 98 55 34 19 40 66 57 19
#> 8 79 3 84 11 95 83 NA NA
#> 9 68 66 NA NA NA NA NA NA
library(dplyr, warn.conflicts = F)
df %>% rowwise() %>%
summarise(last_col = last(na.omit(c_across(everything()))), .groups = 'drop')
#> # A tibble: 9 x 1
#> last_col
#> <int>
#> 1 45
#> 2 20
#> 3 14
#> 4 17
#> 5 69
#> 6 57
#> 7 19
#> 8 83
#> 9 66
Создано 2021-07-17 пакетом reprex (v2.0.0)
Комментарии:
1. Я уже нашел последние значения (извините, если это было неясно), но это еще один отличный пример того, как их найти. Я ищу, чтобы заменить или отфильтровать последнее найденное значение.
2. @ДжефФроули, см. пересмотренный ответ
Ответ №2:
Для замены последнего значения, отличного от NA, в каждой строке на NA
вы можете использовать apply
в базе R —
df[] <- t(apply(df, 1, function(x) {
x[max(which(!is.na(x)))] <- NA
x
}))