Присвойте значения из одного столбца другому на основе уровней другого фактора: R

Я хочу:

  1. сгруппировать по фактору (Site, Pos);
  2. если фактор 'Pos' == "A", присвоить выбранное значение ("a") тем же строкам в новом столбце ("Treat1");
  3. если фактор 'Pos' == "B", присвоить выбранное значение ("b") тем же строкам в новом столбце ("Treat1");
  4. если фактор «Pos» == «AT», присвойте одно значение («a») каждой первой строке нового столбца («Treat 1»), где «Pos» == A, и второе значение («b») каждому второй ряд такой же.

Пока я знаю только, как закодировать первые 3 точки, но этот цикл все еще не работает так, как я ожидал. Он заполняет только последнюю строку в новом столбце Treat1. Любые идеи?

Я очень открыт для различных подходов к этому, но, пожалуйста, имейте в виду, что я новичок в R.

Репро:

yow <- c(1:6) 
Pos <- c("A", "B", "A", "AT", "AT", "B")
df <- as.data.frame(Pos, yow)
df$Site <-  c("low", "low", "high", "high", "high", "high")

df$Treat1 <- NA

for (i in nrow(df %>% group_by(Site)){  
  if(df$Pos[i] == "A"){
    df$Treat1[i] <- "a"
  }
  else {
    if(df$Pos[i] == "B"){
      df$Treat1[i] <- "b"
    }
  }
}

Я ожидаю / ищу:

  • Позиция сайта Treat1
  • низкий А а
  • низкий си б
  • высокая А а
  • высокий уровень АТ
  • высокий АТ б
  • высокая си б

Этот ответ классный, и он выполняет первые 3 шага, в которых мой цикл ifelse терпит неудачу, но он не говорит о 4-й проблеме! R Создать новый столбец значений на основе уровней фактора другого столбца


person sinderJ    schedule 19.05.2020    source источник


Ответы (2)


Вы можете использовать case_when в dplyr :

library(dplyr)

df %>%
  group_by(Pos) %>%
  mutate(Treat1 = case_when(Pos %in% c('A', 'B') ~ tolower(Pos), 
                             Pos == 'AT' ~ c('a', 'b')))


#  Pos     yow Site  Treat1
#  <chr> <int> <chr> <chr> 
#1 A         1 low   a     
#2 B         2 low   b     
#3 A         3 high  a     
#4 AT        4 high  a     
#5 AT        5 high  b     
#6 B         6 high  b     
person Ronak Shah    schedule 19.05.2020
comment
Эй, это отличный ответ! Благодарю вас! - person sinderJ; 19.05.2020
comment
Чудом (я возился с этой проблемой время от времени дольше, чем мне хотелось бы признать), сегодня днем ​​я получил другое решение – НАКОНЕЦ-ТО! Не так аккуратно, как у тебя @Ronak : df$Treat1 <- NA df <- df %>% mutate(Treat1 = case_when( Pos %in% c("A") ~ "a", Pos %in% c("B") ~ "b", )) - person sinderJ; 19.05.2020
comment
Затем: df[df$Pos == "AT", ] <- df[df$Pos == "AT", ] %>% group_by(Site, Pos) %>% mutate(Treat1 = ifelse((row_number() %% 2) == 1, "a", "b")) - person sinderJ; 19.05.2020
comment
Вы можете добавить это как ответ. - person Ronak Shah; 19.05.2020

Другое решение. Не такой аккуратный, как твой Ронак:

df$Treat1 <- NA
df <- df %>% mutate(Treat1 = case_when(
  Pos %in% c("A") ~ "a", 
  Pos %in% c("B") ~ "b",
  ))     

Затем:

df[df$Pos == "AT", ] <- df[df$Pos == "AT", ] %>% group_by(Site,Pos)%>% 
mutate(Treat1 = ifelse((row_number() %% 2) == 1, "a", "b"))
person sinderJ    schedule 10.06.2020