используйте значение из столбца col, чтобы выбрать значение из другого столбца, поместите в новое значение df в R - PullRequest
0 голосов
/ 21 мая 2018

У меня есть df, подобный этому

name <- c("Fred","Mark","Jen","Simon","Ed")
a_or_b <- c("a","a","b","a","b")
abc_ah_one <- c(3,5,2,4,7)
abc_bh_one <- c(5,4,1,9,8)
abc_ah_two <- c(2,1,3,7,6)
abc_bh_two <- c(3,6,8,8,5)
abc_ah_three <- c(5,4,7,6,2)
abc_bh_three <- c(9,7,2,1,4)
def_ah_one <- c(1,3,9,2,7)
def_bh_one <- c(2,8,4,6,1)
def_ah_two <- c(4,7,3,2,5)
def_bh_two <- c(5,2,9,8,3)
def_ah_three <- c(8,5,3,5,2)
def_bh_three <- c(2,7,4,3,0)
df <- data.frame(name,a_or_b,abc_ah_one,abc_bh_one,abc_ah_two,abc_bh_two,
abc_ah_three,abc_bh_three,def_ah_one,def_bh_one,
def_ah_two,def_bh_two,def_ah_three,def_bh_three)

Я хочу использовать значение в столбце "a_or_b", чтобы выбрать значения в каждом из соответствующих столбцов "ah / bh" для каждого "abc" (один, два и три) и поместите его в новый фрейм данных.Например, Фред будет иметь значения 3, 2 и 5 в своем ряду в новом df.Эти значения представляют значения каждой из его категорий «ах» для столбцов abc.Джен, у которой есть «b» в ее столбце a_or_b, будет иметь все свои значения «bh» из своих столбцов abc для своей строки в новом df.Вот как будет выглядеть мой желаемый результат:

combo_one <- c(3,5,1,4,8)
combo_two <- c(2,1,8,7,5)
combo_three <- c(5,4,2,6,4)
df2 <- data.frame(name,a_or_b,combo_one,combo_two,combo_three)

Я попытался сделать это с помощью sapply.Следующее дает мне матрицу правильных столбцов правильных индексов df[grep("abc",colnames(df),fixed=TRUE)] для каждой строки:

sapply(paste0(df$a_or_b,"h"),grep,colnames(df[grep("abc",colnames(df),fixed=TRUE)])) 

Ответы [ 3 ]

0 голосов
/ 21 мая 2018

Это можно сделать с помощью комбинации map и mutate:

require(tidyverse)

df %>%
  select(name, a_or_b, starts_with("abc")) %>%
  rename_if(is.numeric, funs(sub("abc_", "", .))) %>%
  mutate(combo_one = map_chr(a_or_b, ~ paste0(.x,"h_one")),
         combo_one = !!combo_one,
         combo_two = map_chr(a_or_b, ~ paste0(.x,"h_two")),
         combo_two = !!combo_two,
         combo_three = map_chr(a_or_b, ~ paste0(.x,"h_three")),
         combo_three = !!combo_three) %>%
  select(name, a_or_b, starts_with("combo"))

Вывод:

   name a_or_b combo_one combo_two combo_three
1  Fred      a         3         2           5
2  Mark      a         5         1           4
3   Jen      b         1         8           2
4 Simon      a         4         7           6
5    Ed      b         8         5           4
0 голосов
/ 21 мая 2018

Подход Base R будет использовать lapply, мы перебираем каждую строку кадра данных, создаем строку для поиска похожих столбцов, используя paste0 на основе столбца a_or_b, а затем rbind все значения вместе для каждогострока.

new_df <- do.call("rbind", lapply(seq(nrow(df)), function(x) 
 setNames(df[x, grepl(paste0("abc_",df[x,"a_or_b"], "h"), colnames(df))], 
                           c("combo_one", "combo_two", "combo_three"))))

new_df
#  combo_one combo_two combo_three
#1         3         2           5
#2         5         1           4
#3         1         8           2
#4         4         7           6
#5         8         5           4

Мы можем cbind необходимые столбцы:

cbind(df[c(1, 2)], new_df)

#   name a_or_b combo_one combo_two combo_three
#1  Fred      a         3         2           5
#2  Mark      a         5         1           4
#3   Jen      b         1         8           2
#4 Simon      a         4         7           6
#5    Ed      b         8         5           4
0 голосов
/ 21 мая 2018

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

library(dplyr)
library(tidyr)

gather(df, key = "var", value = "val", -name, -a_or_b) %>%
  separate(var, into = c("combo", "h", "ind"), sep = "_") %>%
  mutate(h = substr(h, 1, 1)) %>%
  filter(a_or_b == h, combo == "abc") %>%
  arrange(name) -> result_long
result_long
#     name a_or_b combo h   ind val
# 1     Ed      b   abc b   one   8
# 2     Ed      b   abc b   two   5
# 3     Ed      b   abc b three   4
# 4   Fred      a   abc a   one   3
# 5   Fred      a   abc a   two   2
# 6   Fred      a   abc a three   5
# 7    Jen      b   abc b   one   1
# 8    Jen      b   abc b   two   8
# 9    Jen      b   abc b three   2
# 10  Mark      a   abc a   one   5
# 11  Mark      a   abc a   two   1
# 12  Mark      a   abc a three   4
# 13 Simon      a   abc a   one   4
# 14 Simon      a   abc a   two   7
# 15 Simon      a   abc a three   6

spread(result_long, key = ind, value = val) %>%
  select(name, a_or_b, one, two, three)
#    name a_or_b one two three
# 1    Ed      b   8   5     4
# 2  Fred      a   3   2     5
# 3   Jen      b   1   8     2
# 4  Mark      a   5   1     4
# 5 Simon      a   4   7     6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...