Данные Wrangle в R
Я хотел бы перейти от левой таблицы к правой таблице на изображении ниже, но, похоже, не могу найти логику кодирования, чтобы достичь результата с помощью R.
Ваша помощь очень ценится!
4 ответа
Я создал минимальный пример, который должен делать то, что вы хотите. Основная проблема здесь состоит в том, чтобы сформулировать свой вопрос, поскольку я думаю, что есть лучший ответ, чем мой, чтобы сопоставить значения задержки с модальностью.
library(dplyr)
# --- v0 is your data simplified
v0 <- c("cA", "t1", "t2", "cB", "t3")
# --- indic tels us what are the groups
indic <- v0 %>% stringr::str_detect(string = ., pattern = "c") %>%
cumsum()
# --- here you can try the code line by line (without the %>% (pipe) operator to understand the code
dfr <- tibble(v0, indic)
dfr %>%
group_by(indic) %>%
mutate(v1 = v0[which(stringr::str_detect(v0, "c") )] ) %>%
ungroup() %>%
filter(! stringr::str_detect(v0, "c")) %>%
select(v1, v0)
#> # A tibble: 3 x 2
#> v1 v0
#> <chr> <chr>
#> 1 cA t1
#> 2 cA t2
#> 3 cB t3
# you could also use a loop
Пример использования базы R
:
data <- c(
"cinema A", "17:45", "20:00", "cinema B", "13:00", "15:45", "16:00",
"cinema C", "08:20"
)
time_rows <- grep("cinema", data, invert = TRUE)
data.frame(
time = data[time_rows],
cinema = grep("cinema", data, value = TRUE)[cumsum(grepl("cinema", data))][time_rows]
)
Вот решение для base R
.
Предполагая, что ввод задан как фрейм данных, то есть:
df <- data.frame(X = c("cinema A", 17.45, 20.00, "cinema B", 13.00, 15.45, 16.00, "cinema C", 8.20))
> df
X
1 cinema A
2 17.45
3 20
4 cinema B
5 13
6 15.45
7 16
8 cinema C
9 8.2
следующий код может помочь вам получить таблицу с правой стороны:
lst <- split(df,findInterval(seq(nrow(df)),grep("cinema",df$X)-1,left.open = T))
res <- Reduce(rbind,lapply(lst, function(v) data.frame(ViewingTime = v[-1,],CinemaName = v[1,])))
где выход res
выглядит как:
> res
ViewingTime CinemaName
1 17.45 cinema A
2 20 cinema A
3 13 cinema B
4 15.45 cinema B
5 16 cinema B
6 8.2 cinema C
Как написано в комментариях, предоставьте образцы данных для будущих публикаций. В данном случае я сделал это для вас на основе вашей прикрепленной фотографии.
Есть много способов решить эту проблему. Вот трехэтапный подход.
library(tidyverse)
library(stringr)
# Create the data
df <- tibble(
X1 = c("cinema A", 17.45, 20.00, "cinema B", 13.00, 15.45, 16.00, "cinema C", 8.20))
df
#> # A tibble: 9 x 1
#> X1
#> <chr>
#> 1 cinema A
#> 2 17.45
#> 3 20
#> 4 cinema B
#> 5 13
#> 6 15.45
#> 7 16
#> 8 cinema C
#> 9 8.2
# Step 1: detect where the cinema values are and copy them to a new column
df$cinema <- ifelse(str_detect(df$X1, "cinema"), df$X1, NA)
df
#> # A tibble: 9 x 2
#> X1 cinema
#> <chr> <chr>
#> 1 cinema A cinema A
#> 2 17.45 <NA>
#> 3 20 <NA>
#> 4 cinema B cinema B
#> 5 13 <NA>
#> 6 15.45 <NA>
#> 7 16 <NA>
#> 8 cinema C cinema C
#> 9 8.2 <NA>
# Step 2: replace NA values in the new column with the values above
df <- fill(df, cinema)
df
#> # A tibble: 9 x 2
#> X1 cinema
#> <chr> <chr>
#> 1 cinema A cinema A
#> 2 17.45 cinema A
#> 3 20 cinema A
#> 4 cinema B cinema B
#> 5 13 cinema B
#> 6 15.45 cinema B
#> 7 16 cinema B
#> 8 cinema C cinema C
#> 9 8.2 cinema C
# Step 3: remove the rows where X1 contains cinema information
df <- filter(df, !str_detect(df$X1, "cinema"))
df
#> # A tibble: 6 x 2
#> X1 cinema
#> <chr> <chr>
#> 1 17.45 cinema A
#> 2 20 cinema A
#> 3 13 cinema B
#> 4 15.45 cinema B
#> 5 16 cinema B
#> 6 8.2 cinema C
Создано 26.11.2019 с помощью пакета REPEX (v0.3.0)