#r #dataframe #apply #lapply #data-manipulation
#r #фрейм данных #применить #lapply #манипулирование данными
Вопрос:
У меня есть следующий фрейм данных:
set.seed(1)
df <- data.frame(X1 = sample(c(letters[1:5],NA),10,replace=TRUE),
X2 = sample(c(letters[1:5],NA),10,replace=TRUE),
X3 = sample(c(letters[1:5],NA),10,replace=TRUE),
stringsAsFactors = FALSE)
X1 X2 X3
1 b b <NA>
2 c b b
3 d e d
4 <NA> c a
5 b e b
6 <NA> c c
7 <NA> e a
8 d <NA> c
9 d c <NA>
10 a e c
Я хочу заменить a
на 5, b
на 4, c
на 3, d
на 2 и e
на 1 на:
df %>% lapply(., plyr::mapvalues(, c("a","b","c","d","e"), c(5,4,3,2,1)))
Но это не работает: я получаю предупреждение о том, что в нем отсутствует первый аргумент функции mapvalues()
.
Кто-нибудь знает, что я делаю не так?
Ответ №1:
Простой, но понятный подход:
lookup <- 5:1
names(lookup) <- c("a","b","c","d","e")
df[] <- lapply(df, function(x) lookup[x])
df
X1 X2 X3
1 4 4 NA
2 3 4 4
3 2 1 2
4 NA 3 5
5 4 1 4
6 NA 3 3
7 NA 1 5
8 2 NA 3
9 2 3 NA
10 5 1 3
Обратите внимание, что lookup
это простой именованный вектор, т.е.
> lookup
a b c d e
5 4 3 2 1
И df[]
гарантирует, что вы сохраните структуру фрейма данных при lapply
ее изменении. При вызове lapply
значения в каждом столбце просто используются для поиска по имени в таблице поиска. Чтобы подчеркнуть это, lookup["c"]
возвращает значение «3».
Ответ №2:
Синтаксис использования lapply
немного отличается. Вот как это работает:
df %>% lapply(plyr::mapvalues, from = c("a","b","c","d","e"), to = c(5,4,3,2,1))
$X1
[1] "1" "3" "3" "1" "1" "2" "4" "5" NA "2"
$X2
[1] "2" "1" NA "3" "1" "5" "3" "2" NA NA
$X3
[1] "3" "3" NA "1" NA "1" "1" "2" NA "2"
Если вы все еще хотите иметь dataframe впоследствии, лучше использовать apply
вместо lapply
:
df %>% apply(2, plyr::mapvalues, from = c("a","b","c","d","e"), to = c(5,4,3,2,1)) %>%
as.data.frame(stringsAsFactors = F)
X1 X2 X3
1 4 4 <NA>
2 3 4 4
3 2 1 2
4 <NA> 3 5
5 4 1 4
6 <NA> 3 3
7 <NA> 1 5
8 2 <NA> 3
9 2 3 <NA>
10 5 1 3
Комментарии:
1. он выдает матрицу вместо фрейма данных. И когда я передаю его в dataframe с помощью as.data.frame(), он выдает dataframe, полный factor. Я пытаюсь применить apply, но опять же, это дает матрицу, когда я использую apply.
2. В основном вы устанавливаете
stringsAsFactors = FALSE
, чтобы избежать факторов