Добавление разных символов в список данных через lapply - PullRequest
0 голосов
/ 25 января 2019

Я хочу добавить отдельные элементы вектора символов в виде столбцов в список data.frames. Я могу сделать это вручную, но есть ли более элегантный способ?

# Create sample dfs 
set.seed(1)
df1 <- data.frame("one" = sample(1:10,10,replace=TRUE),
                  "two" = sample(1:10,10,replace=TRUE))

df2 <- data.frame("three" = sample(1:10,10,replace=TRUE),
                  "four" = sample(1:10,10,replace=TRUE))

df3 <- data.frame("five" = sample(1:10,10,replace=TRUE),
                  "six" = sample(1:10,10,replace=TRUE))

# Combine them to list 
dflist = list("df1"=df1,"df2"=df2,"df3"=df3)

# add labelling column 
dflist$df1["label"] <- "a"
dflist$df2["label"] <- "b"
dflist$df3["label"] <- "c"

# With lapply I can only add either "a", "b" or "c" 
dflist = list("df1"=df1,"df2"=df2,"df3"=df3)
labvec <- c("a","b","c")
lapply(dflist,function(x) cbind(x,labvec[2])) # I have to select 1, 2 or 3.

Спрашивается по-другому: Могу ли я также индексировать "labvec" с помощью lapply?

Ответы [ 3 ]

0 голосов
/ 25 января 2019

Решение с lapply() и использованием dplyr::mutate().

library(dplyr)

dflist <- lapply(1:length(dflist), function(i) {
  dflist[[i]] %>% 
    mutate(label = letters[i])
})
# lapply(dflist, head, 2)
# [[1]]
#   one two label
# 1   3   3     a
# 2   4   2     a
# 
# [[2]]
#   three four label
# 1    10    5     b
# 2     3    6     b
# 
# [[3]]
#   five six label
# 1    9   5     c
# 2    7   9     c

Обратите внимание, что это просто "форсирование" lapply(), я имею в виду, это в основном цикл for, а неэто хорошо спрятано.

0 голосов
/ 25 января 2019

Использование tidyverse с map2

library(tidyverse)
map2(dflist, labvec, ~ .x %>% 
                      mutate(label = .y))
#$df1
#   one two label
#1    3   3     a
#2    4   2     a
#3    6   7     a
#4   10   4     a
#5    3   8     a
#6    9   5     a
#7   10   8     a
#8    7  10     a
#9    7   4     a
#10   1   8     a

#$df2
#   three four label
#1     10    5     b
#2      3    6     b
#3      7    5     b
#4      2    2     b
#5      3    9     b
#6      4    7     b
#7      1    8     b
#8      4    2     b
#9      9    8     b
#10     4    5     b

#$df3
#   five six label
#1     9   5     c
#2     7   9     c
#3     8   5     c
#4     6   3     c
#5     6   1     c
#6     8   1     c
#7     1   4     c
#8     5   6     c
#9     8   7     c
#10    7   5     c
0 голосов
/ 25 января 2019

Вы можете использовать Map

Map(`[<-`, x = dflist, i = "label", value = labvec)
#$df1
#  one two label
#1   1   3     a
#2   2   1     a
#3   2   3     a

#$df2
#  three four label
#1     3    1     b
#2     2    1     b
#3     2    1     b

#$df3
#  five six label
#1    3   2     c
#2    2   3     c
#3    3   3     c

x, i и value являются аргументами функции `[<-`, которую мы обычно не называем как в iris['Species2'] <- "a_string_column", где

  • x: iris
  • i: 'Species2'
  • value: "a_string_column"

Та же идея, что и выше, но здесь мы используем анонимную функцию с тремя аргументами (может быть проще для чтения):

Map(function(data, label, value) {data[label] <- value; data}, 
     data = dflist,
     label = "label",
     value = labvec) 

данные

set.seed(1)
df1 <- data.frame("one" = sample(3,replace=TRUE),
                  "two" = sample(3,replace=TRUE))

df2 <- data.frame("three" = sample(3,replace=TRUE),
                  "four" = sample(3,replace=TRUE))

df3 <- data.frame("five" = sample(3,replace=TRUE),
                  "six" = sample(3,replace=TRUE))

# Combine them to list 
dflist = list("df1"=df1,"df2"=df2,"df3"=df3)
...