Как я могу объединить пары переменных, используя суффиксы в R? - PullRequest
0 голосов
/ 19 сентября 2019

У меня очень широкий набор данных (более 1000 столбцов), около 160 из которых являются парами в следующем формате: Var1.r и Var1.s;Var2.r и Var2.s и т. Д.

Вот небольшой пример того, как выглядят данные сейчас:

df <- tibble(Var1.r=c("Apple", "Pear", NA), Var1.s = c(NA, NA, "Dog"), 
             Var2.r = c("Boat", NA, NA), Var2.s = c(NA, "Platypus", NA),
             AnotherVar = c(1,2,3))

# A tibble: 3 x 5
  Var1.r Var1.s Var2.r Var2.s   AnotherVar
  <chr>  <chr>  <chr>  <chr>         <dbl>
1 Apple  NA     Boat   NA                1
2 Pear   NA     NA     Platypus          2
3 NA     Dog    NA     NA                3

И как бы я хотел, чтобы это выглядело:

> df2
# A tibble: 3 x 3
  Var1  Var2     AnotherVar
  <chr> <chr>         <dbl>
1 Apple Boat              1
2 Pear  Platypus          2
3 Dog   NA                3

Я написал функцию для объединения каждой пары столбцов merge_columns, которая принимает два столбца в качестве аргументов и возвращает нужный объединенный столбец.Обычно я делаю что-то вроде:

df2 <- df %>% 
  mutate(Var1 = merge_cols(Var1.r, Var1.s),
         Var2 = merge_cols(Var2.r, Var2.s))

и затем удаляю все столбцы .r и .s.За исключением того, что я не хочу писать ту же самую строку 80 раз.

Должен быть лучший способ, верно?

ОБНОВЛЕНИЕ: я закончил тем, что выбрал уродливое, но работоспособное решение.

# select all the ".s" columns 
# (which will always have their .r counterparts)
to_merge <- df %>% select(ends_with(".s")) %>% names()

S <- NA
# loop through all the .s column names
for (S in to_merge) { 
  R <- gsub('(.+).s', '\\1.r', S) #create the equivalent .r col name
  # merge them using merge_cols() and save them to the .r column 
  df[R] <- merge_cols(df[[S]],df[[R]])
}

# drop all the .s columns
df <- df %>% select(-ends_with(".s"))
# rename the variables that end in .r to be the "main" variable
names(df) <- gsub('(.+).r$', '\\1', names(df))

Это супер уродливо, но работает быстрее, чем изменение формы фрейма данных (потому что у меня слишком много столбцов, но не так много строк) и позволяет мне использовать пользовательскую функцию merge_cols в зависимости от того, как я хочу объединить данные.

1 Ответ

0 голосов
/ 19 сентября 2019

Вы должны быть в состоянии сделать это, преобразовав свой фрейм данных в длинный формат, затем проанализировав имена столбцов с последующим удалением пропущенных значений.Например:

library(dplyr)
library(tidyr)

df <-
  tibble(
    Var1.r = c("Apple", "Pear", NA),
    Var1.s = c(NA, NA, "Dog"),
    Var2.r = c("Boat", NA, NA),
    Var2.s = c(NA, "Platypus", NA),
    AnotherVar = c(1, 2, 3)
  )

df %>% gather(Var, Val, -AnotherVar) %>% 
  separate(Var, into=c("Name", "Suffix"), sep="\\.") %>% 
  drop_na(Val) %>% 
  select(-Suffix) %>% 
  spread(Name, Val)

# A tibble: 3 x 3
  AnotherVar Var1  Var2    
       <dbl> <chr> <chr>   
1          1 Apple Boat    
2          2 Pear  Platypus
3          3 Dog   NA   

Или, говоря немного более обобщенно, перехватите нужные вам переменные gather с помощью starts_with, предполагая, что все они начинаются с Var:

df <-
  tibble(
    Var1.r = c("Apple", "Pear", NA),
    Var1.s = c(NA, NA, "Dog"),
    Var2.r = c("Boat", NA, NA),
    Var2.s = c(NA, "Platypus", NA),
    AnotherVar = c(1, 2, 3),
    AnotherVar2 = c("a", NA, "c"),
    AnotherVar3 = c("a1", "b2", NA)
  )

df %>% gather(Var, Val, starts_with("Var")) %>% 
  separate(Var, into=c("Name", "Suffix"), sep="\\.") %>% 
  drop_na(Val) %>% 
  select(-Suffix) %>% 
  spread(Name, Val)

# A tibble: 3 x 5
  AnotherVar AnotherVar2 AnotherVar3 Var1  Var2    
       <dbl> <chr>       <chr>       <chr> <chr>   
1          1 a           a1          Apple Boat    
2          2 NA          b2          Pear  Platypus
3          3 c           NA          Dog   NA 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...