R Как изменить записи в кадре данных на основе 2 условий - PullRequest
0 голосов
/ 13 января 2020

Использование R для очистки грязных данных. Допустим, у меня есть фрейм данных df:

    Ingredients      Bread  PB  Jam  
1   "Bread,PB,Jam"  
2   "PB,Jam"         x  
3   "Bread"          x  
4   "Bread"                     x  
...

Как бы я настроил условное выражение, которое будет выполнять что-то вроде:
Изменить запись в столбце Ingredients, если она соответствует (Bread, PB, Jam ) столбец имеет x, и без лишних записей, таких как "Хлеб, Хлеб"

Поэтому очищенный столбец Ingredients будет иметь следующий вид:

Ingredients:
"Bread,PB,Jam" 
"Bread,PB,Jam"         
"Bread"               
"Bread,Jam"                     

Большое спасибо!

Ответы [ 2 ]

2 голосов
/ 13 января 2020

Вот базовое решение R согласно вашему описанию

df$Ingredients <- apply(df,1, function(v) {
  if (sum(v[-1]=="x")>0) {
    u <- unique(c(names(v[-1])[which(v[-1]=="x")],unlist(strsplit(v[1],","))))
    paste0(na.omit(u[match(names(v[-1]),u)]),collapse = ",")
  } else {
    v[1]
  }
}
)

такое, что

> df
   Ingredients Bread PB Jam
1 Bread,PB,Jam     o  o   o
2 Bread,Jam,PB     x  o   o
3        Bread     x  o   o
4    Bread,Jam     o  o   x

ДАННЫЕ

df <- structure(list(Ingredients = c("Bread,PB,Jam", "PB,Jam", "Bread", 
"Bread"), Bread = c("o", "x", "x", "o"), PB = c("o", "o", "o", 
"o"), Jam = c("o", "o", "o", "x")), class = "data.frame", row.names = c(NA, 
-4L))
1 голос
/ 13 января 2020

Мы можем разделить запятую Ingredients на разные строки, получить все значения столбцов в длинном формате, group_by каждое row и paste значения unique отсортированным образом.

library(dplyr)
library(tidyr)

df %>%
  mutate(row = row_number()) %>%
  #mutate_all(~na_if(., "")) %>% #Use this if you have blank values instead of NA
  separate_rows(Ingredients, sep = ",") %>%
  pivot_longer(cols = -row, values_drop_na = TRUE) %>%
  mutate(value = ifelse(value == 'x', name, value)) %>%
  group_by(row) %>%
  summarise(Ingredients = toString(sort(unique(value)))) %>%
  select(-row)

# A tibble: 4 x 1
#  Ingredients   
#  <chr>         
#1 Bread, PB, Jam
#2 Bread, PB, Jam
#3 Bread         
#4 Bread, Jam    

данные

df <- structure(list(Ingredients = structure(c(2L, 3L, 1L, 1L), .Label = c("Bread", 
"Bread,PB,Jam", "PB,Jam"), class = "factor"), Bread = structure(c(NA, 
1L, 1L, NA), .Label = "x", class = "factor"), PB = c(NA, NA, 
NA, NA), Jam = structure(c(NA, NA, NA, 1L), .Label = "x", class = 
"factor")), class = "data.frame", row.names = c("1", "2", "3", "4"))
...