Создать из фрейма данных DF с двоичными значениями в зависимости от условий - PullRequest
3 голосов
/ 10 мая 2019

У меня есть фрейм данных, например;

   Groups   Value
    G1  NA
    G1  NA
    G1  NA
    G1  23
    G2  NA
    G2  NA
    G2  NA
    G2  NA
    G2  NA
    G2  NA
    G3  34
    G3  21
    G4  NA
    G4  NA
    G5  NA
    G5  45

и я ищу код в R для того, чтобы получить другой фрейм данных с двоичными значениями (1 для хотя бы одного значения в группе было> = 1) и (0 для групп, содержащих только значения NA)

и получите новую дейтаграмму, такую ​​как:

G1  G2  G3  G4  G5
1   0   1   0   1

Спасибо за вашу помощь.

Ответы [ 4 ]

3 голосов
/ 10 мая 2019

Мы можем сделать с table с base R. Получить столбец «Значение» в качестве логического вектора (!is.na) и найти таблицу частот с помощью «Группы», проверить, превышает ли частота значение 0, преобразовать логический вектор в двоичный с помощью as.integer или +

+(table(df1$Groups, !is.na(df1$Value))[,2] > 0)
# G1 G2 G3 G4 G5 
# 1  0  1  0  1 

Или используя rowsum из base R

rowsum(+!is.na(df1$Value), df1$Groups)

ПРИМЕЧАНИЕ: оба вышеуказанных метода base R - пакеты не используются


Или используя tidyverse

library(tidyverse)
df1 %>% 
  group_by(Groups) %>%
  summarise_all(list(~ as.integer(sum(!is.na(.)) > 0)))
# A tibble: 5 x 2
#  Groups Value
#   <chr>  <int>
#1 G1         1
#2 G2         0
#3 G3         1
#4 G4         0
#5 G5         1

или с data.table

library(data.table)
setDT(df1)[, +(sum(!is.na(Value)) > 0), Groups]

данные

df1 <- structure(list(Groups = c("G1", "G1", "G1", "G1", "G2", "G2", 
"G2", "G2", "G2", "G2", "G3", "G3", "G4", "G4", "G5", "G5"), 
    Value = c(NA, NA, NA, 23L, NA, NA, NA, NA, NA, NA, 34L, 21L, 
    NA, NA, NA, 45L)), class = "data.frame", row.names = c(NA, 
-16L))
1 голос
/ 10 мая 2019

Мы можем использовать базу R aggregate

aggregate(Value > 1~Groups, df1, any, na.rm = TRUE, na.action = na.pass)

#  Groups Value > 1
#1     G1      TRUE
#2     G2     FALSE
#3     G3      TRUE
#4     G4     FALSE
#5     G5      TRUE

Если вам нужно 1/0 значения вместо TRUE/FALSE, вы можете сделать

aggregate(Value~Groups, df1, function(x) 
           +(any(x > 1, na.rm = TRUE)), na.action = na.pass)

#  Groups Value
#1     G1     1
#2     G2     0
#3     G3     1
#4     G4     0
#5     G5     1
1 голос
/ 10 мая 2019

С dplyr вы также можете сделать:

df %>%
 group_by(Groups) %>%
 summarise(Value = as.integer(any(!is.na(Value))))

  Groups Value
  <chr>  <int>
1 G1         1
2 G2         0
3 G3         1
4 G4         0
5 G5         1

Или:

df %>%
 group_by(Groups) %>%
 summarise(Value = as.integer(max(Value, na.rm = TRUE) > 0))
0 голосов
/ 10 мая 2019

с помощью условия зацикливания мы можем извлечь то же самое

данные

data <- data.frame (Groups =rep(c("G1","G2"), each = 4),  Value = c(NA,NA,NA,23,NA,NA,NA,NA))

Loop

for (i in unique(data$Groups)){
  data$new_value[data$Groups==i] <- ifelse(sum(data$Value[data$Groups==i],na.rm = T)>1,1,0)
}


data1 <- unique(data[,c(1,3)])

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