Получить имена столбцов в новую переменную на основе условий

У меня есть такой фрейм данных, и я делаю это на R. Мои проблемы можно разделить на два этапа.

СУБИД азбука BCD ДЭФ 192838 4 -3 2 193928 -6 -2 6 205829 4 -5 9 201837 3 4 4

Я хочу создать новую переменную, содержащую список имен столбцов с отрицательным значением для каждого SUBID. Вывод должен выглядеть примерно так:

СУБИД азбука BCD ДЭФ вывод 192838 4 -3 2 "БКД" 193928 -6 -2 6 "Азбука", "BCD" 205829 4 -5 9 "БКД" 201837 3 4 4 " "

И затем, на втором этапе, я хотел бы свернуть SUBID в более общий идентификатор и получить количество уникальных строк из выходной переменной для каждого идентификатора (мне просто нужно число, конкретные строки в скобках только для иллюстрацию).

СУБИД вывод 19 2 ("Азбука", "BCD") 20 1 ("BCD")

Это два шага, которые, как я думаю, должны быть выполнены, но, возможно, есть способ пропустить первый шаг и сразу перейти ко второму шагу, которого я не знаю. Я был бы признателен за любую помощь, так как сейчас я не уверен, с чего начать. Спасибо!

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
51
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это отвечает на первую часть вашего вопроса, вторую я не понял

 df$output <-apply(df[,-1], 1, function(x) paste(names(df)[-1][x<0], collapse = ","))
 df
   SUBID ABC BCD DEF  output
1 192838   4   3  -2     DEF
2 193928  -6  -2   6 ABC,BCD
3 205829   4  -5   9     BCD
4 201837   3   4   4        

Для второй части попробуйте следующее:

id <- sapply(strsplit(sub("\\W+", "",  df$output), split = ""), function(x){
  sum(!(duplicated(x) | duplicated(x, fromLast = TRUE)))
} )


   data.frame(SUBID = substr(df$SUBID, 1,2), output = id, string = df$output)
      SUBID output  string
    1    19      3     DEF
    2    19      2 ABC,BCD
    3    20      3     BCD
    4    20      0  

Я добавил переменную string, чтобы убедиться, что с вашим количеством уникальных значений все в порядке.

Спасибо! Во второй части я хотел свернуть 6-значный subid в 2-значный идентификатор на основе первых двух цифр (19,20), а затем получить количество уникальных строк в выводе, созданном в части 1. , У меня есть опечатка в исходных данных вопроса, так что, возможно, вы запутались.

sucksatmath 21.11.2022 22:04

Пожалуйста, добавьте некоторое объяснение того, что делают apply, collapse, sapply.

Ed_Gravy 21.11.2022 22:22
Ответ принят как подходящий

Другой путь:

library(dplyr)
library(tidyr)

df <- df %>% pivot_longer(-SUBID)

df1 <- df %>%
  group_by(SUBID) %>%
  summarise(output = paste(name[value < 0L], collapse = ','))

df2 <- df %>%
  group_by(SUBID = substr(SUBID, 1, 2)) %>%
  summarise(output_count = n_distinct(name[value < 0L]),
            output = paste0(output_count, ' (', paste(name[value < 0L], collapse = ','), ')'))

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

df1

# A tibble: 4 x 2
   SUBID output   
   <int> <chr>    
1 192838 "BCD"    
2 193928 "ABC,BCD"
3 201837 ""       
4 205829 "BCD"    

df2

# A tibble: 2 x 3
  SUBID output_count output         
  <chr>        <int> <chr>          
1 19               2 2 (BCD,ABC,BCD)
2 20               1 1 (BCD)   

Красивый! Я думаю, что OP просто искал счет в финале, а не вектор значений.

Dan Adams 21.11.2022 22:14

Спасибо! Я увидел комментарий сейчас и изменил.

arg0naut91 21.11.2022 22:18

Что делает collapse? Кстати, ваш ответ намного легче понять, поэтому спасибо за это.

Ed_Gravy 21.11.2022 22:26

это аргумент функции paste() и указывает разделитель, который следует использовать при объединении вектора строк в одну строку. См. ?paste в Rstudio.

Dan Adams 21.11.2022 22:27

Действительно, как объяснил @DanAdams. Вы также можете использовать, например, toString(name[value < 0L]), но paste с collapse дает больше свободы в отношении разделителя.

arg0naut91 21.11.2022 22:33

Один из вариантов — воспользоваться dplyr::cur_data() для доступа к names() данным и подмножеству на основе ваших критериев. Затем вы можете воспользоваться tibble list-columns, чтобы сохранить набор имен столбцов произвольной длины и, наконец, вычислить количество уникальных значений в этом списке.

library(tidyverse)

d <- structure(list(SUBID = c(192838, 193928, 205829, 201837), ABC = c(4, -6, 4, 3), BCD = c(-3, -2, -5, 4), DEF = c(2, 6, 9, 4)), row.names = c(NA, -4L), class = "data.frame")

d %>% 
  rowwise() %>%
  mutate(neg_col_names = list(names(cur_data())[cur_data() < 0])) %>% 
  group_by(ID_grp = str_sub(SUBID, 1, 2)) %>% 
  summarize(neg_col_count = n_distinct(unlist(c(neg_col_names))))

#> # A tibble: 2 × 2
#>   ID_grp neg_col_count
#>   <chr>          <int>
#> 1 19                 2
#> 2 20                 1

Created on 2022-11-22 with reprex v2.0.2

Другие вопросы по теме