Упрощение таблиц (их сжатие!) в R- basic q

#r

#r

Вопрос:

У меня есть базовый q, в котором я хотел бы быстро найти R-решение…

У меня есть таблица с разделителями табуляции с несколькими строками, но я хочу «объединить» все строки в одну… например:

 name   day  red  blue   orange  black
bill    1   yes         
bill    2        yes        
bill    3                        yes
bill    4                 no    
 

Но я хочу, чтобы результат не зависел от дня:

 name    red blue    orange  black
bill    yes yes      no      yes
 

Итак, по сути, я сокращаю таблицу, чтобы включить все ответы независимо от дня. ПРИМЕЧАНИЕ: никогда не бывает никаких совпадений, т. Е. Билл будет выбирать только один цвет в день.

Я мог бы сделать это в Excel, но я бы предпочел найти R-решение… рад получить рекомендации даже о том, какие библиотеки были бы полезны :).

Полегче со мной, я клиницист, а не биоинформатик!

Ответ №1:

Вот вариант с dplyr . Если пропущенные значения "" , после группировки по «имени», summarise путем across перебора столбцов и получения элементов, которые не являются пустыми ( .[. != ""] )

 library(dplyr)
df1 %>%
   group_by(name) %>%
   summarise(across(red:black, ~ .[.!= '']))
 

Или, если пропущенные значения NA

 df1 %>%
     group_by(name) %>%
     summarise(across(red:black, ~ .[!is.na(.)]))
 

Если имеется более одного не пропускающего элемента, приведенный выше результат будет list столбцом. Вместо этого мы также можем paste сделать это вместе

 df1 %>%
     group_by(name) %>%
     summarise(across(red:black, ~ toString(.[!is.na(.)])))
 

Если есть оба NA и "" , можно преобразовать "" в NA , а затем использовать is.na или complete.cases или с na.omit

 df1 %>%
 group_by(name) %>%
 summarise(across(red:black, ~ toString(na.omit(na_if(., "")))))
 

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

1. ты звезда! Существует более одного не пропускающего элемента, поэтому единственным, который сработал, было ваше третье решение. Не уверен, куда я иду отсюда, превращая вывод в читаемый фрейм данных, хотя … извиняюсь, если я глуп!

2. @lecb Для двух других это будут list столбцы

3. Один последний вопрос (извинения)… кажется, что все символьные значения имеют 2 завершающие запятые после текста .. но только после выполнения кода … ?!

4. @lecb Это из последнего блока кода. toString(c('a', 'b')) преобразуется в одну строку с , разделенными

5. ДА. Я предполагаю, что когда значения склеиваются вместе, оно принимает пропущенное значение…

Ответ №2:

В base R вы могли бы использовать aggregate и выбирать непустые значения для каждого имени.

 aggregate(cbind(red,blue,orange,black)~name, df, function(x) toString(x[x!='']))

#  name red blue orange black
#1 bill yes  yes     no   yes
 

данные

 df <- structure(list(name = c("bill", "bill", "bill", "bill"), day = 1:4, 
    red = c("yes", "", "", ""), blue = c("", "yes", "", ""), 
    orange = c("", "", "", "no"), black = c("", "", "yes", ""
    )), class = "data.frame", row.names = c(NA, -4L))