Как объединить строки с определенными именами в R

#r #merge #dplyr

#r #слияние #dplyr

Вопрос:

У меня есть фрейм данных с несколькими повторяющимися строками из цикла:

                      v1     v2     v3    v4
  Number              1     2      3     5
  Index               0     0      0     0
  Number.1            1     2      3     5
  Index.1             0     0      0     0
  Number.2            1     2      3     5
  Index.2             0     0      0     0
  Number.3            1     2      3     5
  Index.3             0     0      0     0
  Number.4            1     2      3     5
  Index.4             0     0      0     0
  Number.5            1     2      3     5
  Index.5             0     0      0     0
  

Я хочу добавить все строки с «числом» в виде одной строки значений, каждая из которых находится в одном отдельном столбце

                       v1     v2     v3   v4    v5     v6     v7    v8
  Number              1     2      3     5      1     2      3     5   etc
  

Я не нашел ни одного простого способа сделать это, хотя это кажется простым.
Я пытался использовать dplyr подобным образом, но безуспешно:

   df[,rownames(df)%in%(grep("Number*", rownames(df))]
  

Комментарии:

1. Я думаю, вам нужно , после c(t(df[rownames(df)%in%(grep("Number*", rownames(df)),]))

Ответ №1:

Вот довольно запутанное dplyr решение — объяснение во встроенных комментариях.

 library(tidyverse)

df2 <- df %>%
  mutate(row_name = rownames(.)) %>% # Add a new column with the row names
  filter(grepl("Number", row_name)) %>% # filter against a match for 'Number'
  select(-row_name) %>% # Get rid of that column
  t() %>% # Transpose
  map(unlist, use.names = F) %>% # Flatten
  as.data.frame() %>% # Convert to a df so we can change the row name later
  `colnames<-`(paste0("v", seq(1:ncol(.)))) %>%  # Add colnames to your format
  `rownames<-`("Number") # Add the row name
  

Результат:

        v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18
Number  1  2  3  1  2  3  1  2  3   1   2   3   1   2   3   1   2   3
  

Ответ №2:

Мы берем transpose и concatenate ( c ), чтобы получить vector

 i1 <-  rownames(df)%in%(grep("Number(\.\d)*", rownames(df), value = TRUE))
v1 <- c(t(df[i1, ]))
  

ПРИМЕЧАНИЕ: grep возвращает индекс, поэтому нет необходимости выполнять %in% повторные действия для сопоставления с именами строк

 i2 <- grep("Number(\.\d)*", rownames(df))
  

было бы достаточно подмножества

 v2 <- c(t(df[i2, ]))
  

Лучше иметь его как вектор, а не как data.frame. Если нам действительно нужна одна строка data.frame с таким количеством столбцов

 as.data.frame.list(v1)
  

ПРИМЕЧАНИЕ2: слегка изменен шаблон, чтобы соответствовать . следующей цифре, если таковая имеется. В коде операционной системы он будет проверять Number* , т.Е. 0 или более ‘r’ (хотя он работал в данных)

Комментарии:

1. Это работает как шарм! Я думал, что это было бы проще сделать, но это работает так, как задумано