Создать двоичную таблицу из длинной таблицы (например, tidyr :: spread ()) - PullRequest
1 голос
/ 21 апреля 2020

В качестве входных данных для модели дерева я создал таблицу анализа в SQL. Теперь я хочу перенести его в R, потому что модель, в которой эта таблица используется в качестве входных данных, также выполняется в R. Один из шагов SQL, который я не могу преобразовать в R.

Таблица анализа имеет следующий вид:

df <- data.frame(
  pseudonym = c("a", "a", "a", "b", "c", "c"),
  var1 = c(1,1,0,1,1,0),
  var2 = c(1,0,0,0,0,1),
  var3 = c(0,0,0,0,0,1))

> df
  pseudonym var1 var2 var3
1         a    1    1    0
2         a    1    0    0
3         a    0    0    0
4         b    1    0    0
5         c    1    0    0
6         c    0    1    1

На следующем шаге мне нужны отдельные строки для псевдонима с сохранением информации (1) из других столбцов var1, var2, var3 . (В SQL это создается через max(case when...then 1 else 0 end) as var1)

Таким образом, результат df2 , созданный из df1 , должен быть

df2 <- data.frame(
  pseudonym = c("a", "b", "c"),
  var1 = c(1,1,1),
  var2 = c(1,0,1),
  var3 = c(0,0,1))

> df2
  pseudonym var1 var2 var3
1         a    1    1    0
2         b    1    0    0
3         c    1    1    1

It было бы очень полезно, если у кого-то есть идея.

Ответы [ 3 ]

1 голос
/ 21 апреля 2020

Мы можем использовать max

library(data.table)
setDT(df)[, lapply(.SD, max), pseudonym]
#  pseudonym var1 var2 var3
#1:         a    1    1    0
#2:         b    1    0    0
#3:         c    1    1    1
1 голос
/ 21 апреля 2020

Вот один из способов:

library(dplyr)
library(tidyr)

df <- data.frame(
  pseudonym = c("a", "a", "a", "b", "c", "c"),
  var1 = c(1,1,0,1,1,0),
  var2 = c(1,0,0,0,0,1),
  var3 = c(0,0,0,0,0,1))

df %>% 
  pivot_longer(cols = var1:var3) %>% 
  group_by(pseudonym, name) %>% 
  filter(max(value) == value) %>% 
  ungroup() %>% 
  distinct() %>% 
  pivot_wider(names_from = name, values_from = value)

#># A tibble: 3 x 4
#>  pseudonym  var1  var2  var3
#>  <fct>     <dbl> <dbl> <dbl>
#>1 a             1     1     0
#>2 b             1     0     0
#>3 c             1     1     1
0 голосов
/ 21 апреля 2020

Другой подход, который может быть не очень сложным, но работает:

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
df <- data.frame(
    pseudonym = c("a", "a", "a", "b", "c", "c"),
    var1 = c(1,1,0,1,1,0),
    var2 = c(1,0,0,0,0,1),
    var3 = c(0,0,0,0,0,1)); df
#>   pseudonym var1 var2 var3
#> 1         a    1    1    0
#> 2         a    1    0    0
#> 3         a    0    0    0
#> 4         b    1    0    0
#> 5         c    1    0    0
#> 6         c    0    1    1

df2 <- df %>% group_by(pseudonym) %>% mutate(var1 = case_when(1 %in% var1 ~ 1),
                                      var2 = case_when(1 %in% var2 ~ 1),
                                      var3 = case_when(1 %in% var3 ~ 1)) %>% 
                                      unique() %>% replace(is.na(.), 0) %>%
    ungroup(); df2
#> # A tibble: 3 x 4
#>   pseudonym  var1  var2  var3
#>   <fct>     <dbl> <dbl> <dbl>
#> 1 a             1     1     0
#> 2 b             1     0     0
#> 3 c             1     1     1

Создан в 2020-04-21 пакетом Представить (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...