Замена значений в нескольких столбцах значениями из тех же столбцов в разных строках в зависимости от условий - PullRequest
0 голосов
/ 10 апреля 2020

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

Сокращенный пример мои данные выглядят так:

data <- data.frame(cbind(
          id=c(1:7),
          set = c(1,2,2,3,1,3,2),
          choice = c("A1","A2","A1","A1","A2","A2","A2"),
          parameter1=c("blue","green","red","red","orange","blue","green"),
          parameter2=c("low", "low","high","medium","high","high","low")
          ))

data

  id set choice parameter1 parameter2
1  1   1     A1       blue        low
2  2   2     A2      green        low
3  3   2     A1        red       high
4  4   3     A1        red     medium
5  5   1     A2     orange       high
6  6   3     A2       blue       high
7  7   2     A2      green        low

Конкретно, я пытаюсь заменить значения параметра 1 и параметра 2 для набора значениями параметра 1 и параметра 2 того же набора, но с другим выбором. Таким образом, для первой строки, set = 1 и choice = A1, я хочу заменить параметр 1 и параметр 2 на значения из строки 5, поскольку это тот же набор (= 1), но альтернативный выбор (A2).

У меня больше параметров и наборов в полном наборе данных, поэтому решение должно быть обобщено для большего количества параметров и наборов выбора. Кроме того, если это уместно, наборы и соответствующие варианты выбора появляются несколько раз, но всегда с одинаковыми значениями параметров.

Я знаю, что могу написать все это с различными типами условий if, но это будет ошибкой склонны (и не весело вообще). Может быть, у кого-то есть идея о том, как go сделать это умным способом?

(Это мой первый вопрос, надеюсь, это имеет смысл, и это достаточно ясно).

РЕДАКТИРОВАТЬ для пояснения: я собираюсь заменить набор 1, значения А2 на набор 1, значения А1 и наоборот, при этом количество наблюдений останется неизменным. Желаемый результат будет выглядеть так:

  id set choice  parameter1 parameter2
1  1   1     A1      orange       high  
2  2   2     A2         red       high
3  3   2     A1       green        low
4  4   3     A1        blue       high 
5  5   1     A2        blue        low
6  6   3     A2         red     medium
7  7   2     A2         red       high

Ответы [ 2 ]

0 голосов
/ 10 апреля 2020

Это должно работать с вашими образцами данных и в большем масштабе. Ваши данные:

data <- data.frame(cbind(
  id=c(1:7),
  set = c(1,2,2,3,1,3,2),
  choice = c("A1","A2","A1","A1","A2","A2","A2"),
  parameter1=c("blue","green","red","red","orange","blue","green"),
  parameter2=c("low", "low","high","medium","high","high","low")
),stringsAsFactors = FALSE)

R код:

Сначала мы создаем ключ в первой таблице, объединяя набор и выбор столбцов. В соответствии с вашими ожиданиями мы создаем еще одну таблицу, в которой мы генерируем ключ для соединения двух таблиц (мы используем substr и одну ifelse). Затем мы объединяем две таблицы, сохраняя уникальные идентификаторы и удаляя помощники столбцов.

library(stringi)
library(dplyr)
    data$new3=paste0(data$set,data$choice)
    df=data[,1:3]
    df$new=stri_sub(df$choice,-1,-1)
    df$new2=ifelse(df$new==1,2,1)
    df$new3=paste0(df$set,stri_sub(df$choice,1,1),df$new2)
    df %>% left_join(select(data, starts_with("parameter"),new3), by = "new3") %>% 
      distinct(id,.keep_all = TRUE) %>%
      select(-starts_with("new"))

Вывод:

  id set choice parameter1 parameter2
1  1   1     A1     orange       high
2  2   2     A2        red       high
3  3   2     A1      green        low
4  4   3     A1       blue       high
5  5   1     A2       blue        low
6  6   3     A2        red     medium
7  7   2     A2        red       high
0 голосов
/ 10 апреля 2020

База R (рядом с решением):

# Take a subset of the unique ids and sets: params_inverted => data.frame
params_inverted <- unique(data[,c("set", "choice")])

# Invert the choices: levels(data$choice) => factor levels
levels(data$choice) <- rev(levels(data$choice))

# Merge with the original data.frame: params_inverted => data.frame
params_inverted <- merge(
  params_inverted,
  data[, c("set", "choice", grep("param", names(data), value = TRUE))],
  by = c("set", "choice"),
  all.x = TRUE
)

Данные:

data <- data.frame(cbind(
  id=c(1:7),
  set = c(1,2,2,3,1,3,2),
  choice = c("A1","A2","A1","A1","A2","A2","A2"),
  parameter1=c("blue","green","red","red","orange","blue","green"),
  parameter2=c("low", "low","high","medium","high","high","low")
))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...