#r #list #data-cleaning
#r #Список #очистка данных
Вопрос:
Я хотел бы заменить значения внутри столбца именем списка, зависящим от значений, находящихся внутри значений списка:
df <- data.frame(Activity = c("Checking emails", "Playing games", "Reading", "Watching TV",
"Watching YouTube", "Watching TV", "Relaxing", "Getting ready",
"Working/ studying", "Relaxing"))
mylist <-list(Tech_activity = c("Browsing social media", "Checking emails",
"Video calling", "On my computer/ PC", "Watching YouTube", "Browsing the internet",
"On my phone", "Watching TV"), Socialising = c("Spending time with friends",
"Chatting/ talking/ having a conversation", "Spending time with family"
), Work = "Working/ studying", Transport = c("Travelling", "Walking",
"Driving"), Household = c("Housework", "Cooking"), Leisure = c("Exercising/ Working out",
"Getting ready", "Exercising/ working out", "Hobbies eg knitting",
"Playing games", "Shopping", "Eating", "Listening to music",
"Reading", "Smoking", "Playing with pets", "Personal caring",
"Personal care", "Nothing", "Relaxing", "Waiting"))
Итак, если значение фрейма данных находится в значениях элемента в списке, замените df на это имя элемента, если нет, пропустите этот элемент и проверьте следующий элемент списка и так далее. (Пожалуйста, извините за двойной цикл for).
for (i in df$Activity){
for (j in mylist){
if (i %in% mylist[j]){
i <- names(mylist[j])
}
}
}
Заранее благодарим вас за любую помощь.
Ответ №1:
Вы можете создать mylist
как dataframe, а затем merge
использовать его df
.
merge(df, stack(mylist), by.x = 'Activity', by.y = 'values')
tidyverse
Способ был бы :
library(tidyverse)
enframe(mylist) %>%
unnest(value) %>%
right_join(df, by = c('value' = 'Activity'))
# name value
# <chr> <chr>
# 1 Tech_activity Checking emails
# 2 Tech_activity Watching YouTube
# 3 Tech_activity Watching TV
# 4 Tech_activity Watching TV
# 5 Work Working/ studying
# 6 Leisure Getting ready
# 7 Leisure Playing games
# 8 Leisure Reading
# 9 Leisure Relaxing
#10 Leisure Relaxing
Комментарии:
1. Вау, очень полезно, спасибо. Такой перспективы у меня не было
Ответ №2:
В базовом R:
matches <- unlist(lapply(mylist, function(x) which(df$Activity %in% x)))
df$Activity[matches] <- gsub("\d $", "", names(matches))
df
#> Activity
#> 1 Tech_activity
#> 2 Leisure
#> 3 Leisure
#> 4 Tech_activity
#> 5 Tech_activity
#> 6 Tech_activity
#> 7 Leisure
#> 8 Leisure
#> 9 Work
#> 10 Leisure
Комментарии:
1. Я попытался принять оба ответа, поскольку они правильные и отличные, но это позволит мне сделать только один
2. @ElliotM нет проблем. Выберите тот, который лучше всего отвечает на ваш вопрос.
Ответ №3:
Мы можем использовать tidyverse
library(tibble)
library(purrr)
library(dplyr)
enframe(mylist, value = 'Activity') %>%
unnest(c(Activity)) %>%
inner_join(df)
-вывод
# A tibble: 10 x 2
# name Activity
# <chr> <chr>
# 1 Tech_activity Checking emails
# 2 Tech_activity Watching YouTube
# 3 Tech_activity Watching TV
# 4 Tech_activity Watching TV
# 5 Work Working/ studying
# 6 Leisure Getting ready
# 7 Leisure Playing games
# 8 Leisure Reading
# 9 Leisure Relaxing
#10 Leisure Relaxing