Сопоставить / заменить несколько столбцов фрейма данных, соответствующих другому фрейму данных в R - PullRequest
0 голосов
/ 10 февраля 2019

Начну с того, что я пытаюсь выучить r, но мне нелегко.Аналогично этому сообщению здесь Я пытаюсь сопоставить значения в нескольких столбцах одного фрейма данных (df), а затем заменить эти значения на основе соответствующих столбцов из другого фрейма данных (df.key).Вот мой пример df:

name  type place ttotal t01 t02 t03 t04 t05 t06 t07 t08 t09
joe   cat  SE        7    3   2   2   3   2  5   2   0  1  
john  cat  SE        2    0   0   4   0   3  1   3   1  7
sue   cat  SE        1    2   0   5   0   4  1   4   3  0     
jack  cat  SE        6    3   4   2   2   4  0   2   1  5    

Ниже приведен мой df.key, который будет использоваться для сопоставления значений в столбцах от df $ ttotal до t09 с классом df.key $ и замены их значениями в df.введите $ mid соответственно:

lo  hi class mid 
0    0    0  0.0
0    1    1  0.5
1    2    2  3.0    
5   10    3  7.5   
10  20    4 15.0 
20  30    5 25.0 
30  40    6 35.0 
40  50    7 45.0 

, поэтому первая строка должна быть:

name  type place ttotal t01  t02  t03 t04 t05 t06  t07 t08 t09
 joe   cat  SE   45.0   7.5  3.0  3.0 7.5 3.0 25.0 3.0 0.0 0.5

Вот только один цикл сопоставления, который я пробовал, но он заполняет полученное значение по строке:

for(i in 1:dim(df)[1]){
  for(j in df$4:13) {
    df[i,j] <- df.key$mid[match(i, df.key$class)]
  }
}

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

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Вы можете просто сопоставить свои ключи с вашими данными:


library(tidyverse)

mutate_at(dat, vars(ttotal:t09), funs(map_dbl(., ~ keys$mid[keys$class == .x])))

Какие выходные данные:

  name type place ttotal t01 t02 t03 t04  t05  t06  t07 t08  t09
1  joe  cat    SE   45.0 7.5   3   3 7.5  3.0 25.0  3.0 0.0  0.5
2 john  cat    SE    3.0 0.0   0  15 0.0  7.5  0.5  7.5 0.5 45.0
3  sue  cat    SE    0.5 3.0   0  25 0.0 15.0  0.5 15.0 7.5  0.0
4 jack  cat    SE   35.0 7.5  15   3 3.0 15.0  0.0  3.0 0.5 25.0

Объяснение:

С помощью dplyr::mutate_at() вы можете изменять значения переменных, которые вы выбираете с помощью vars(ttotal:t09), применяя функцию funs(...) к каждой из выбранных переменных.Для каждой переменной map_dbl(., ~ keys$mid[keys$class == .x]) сравнивает ее с keys$class поэлементно (key$class == .x) и подмножествами keys$mid, получая логический вектор.


Ваши данные:

dat <-
  structure(
    list(
      name = c("joe", "john", "sue", "jack"),
      type = c("cat",
               "cat", "cat", "cat"),
      place = c("SE", "SE", "SE", "SE"),
      ttotal = c(7L,
                 2L, 1L, 6L),
      t01 = c(3L, 0L, 2L, 3L),
      t02 = c(2L, 0L, 0L, 4L),
      t03 = c(2L, 4L, 5L, 2L),
      t04 = c(3L, 0L, 0L, 2L),
      t05 = c(2L,
              3L, 4L, 4L),
      t06 = c(5L, 1L, 1L, 0L),
      t07 = c(2L, 3L, 4L,
              2L),
      t08 = c(0L, 1L, 3L, 1L),
      t09 = c(1L, 7L, 0L, 5L)
    ),
    class = "data.frame",
    row.names = c(NA,-4L)
  )

keys <-
  structure(
    list(
      lo = c(0L, 0L, 1L, 5L, 10L, 20L, 30L, 40L),
      hi = c(0L,
             1L, 2L, 10L, 20L, 30L, 40L, 50L),
      class = 0:7,
      mid = c(0, 0.5,
              3, 7.5, 15, 25, 35, 45)
    ),
    class = "data.frame",
    row.names = c(NA,-8L)
  )
0 голосов
/ 10 февраля 2019

Может сделать:

library(tidyverse)

df %>%
  gather(key, val, ttotal:t09) %>%
  left_join(df.key %>% select(3:4), by = c("val" = "class")) %>%
  spread(key, mid) %>%
  group_by(name) %>%
  summarise_all(funs(first(na.omit(.)))) %>%
  select(-val)

Вывод:

# A tibble: 4 x 13
  name  type  place   t01   t02   t03   t04   t05   t06   t07   t08   t09 ttotal
  <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>
1 jack  cat   SE      7.5    15     3   3    15     0     3     0.5  25     35  
2 joe   cat   SE      7.5     3     3   7.5   3    25     3     0     0.5   45  
3 john  cat   SE      0       0    15   0     7.5   0.5   7.5   0.5  45      3  
4 sue   cat   SE      3       0    25   0    15     0.5  15     7.5   0      0.5
...