Сделать имя объекта новым столбцом в фрейме данных с помощью lapply - PullRequest
0 голосов
/ 13 марта 2020

У меня есть следующие данные

x <- list(a=c(1, 2, 3),b=c(4, 5, 6),c=c(7, 8, 9))

и функция, которая преобразует данные в фрейм данных с lapply()

to_dataframe <- function(x){
  d <- data.frame(Y = as.matrix(x))
}
lapply(x, to_dataframe)

Выходные данные

$a
  Y
1 1
2 2
3 3

$b
  Y
1 4
2 5
3 6

$c
  Y
1 7
2 8
3 9

Мне бы хотелось, чтобы вывод был

```r
$a
  Y name
1 1 a
2 2 a
3 3 a

$b   
  Y name
1 4 b
2 5 b
3 6 b

$c
  Y name
1 7 c
2 8 c
3 9 c

У меня возникли трудности с установкой значения столбца name в качестве имени объекта. Что мне делать с этого момента?

Ответы [ 3 ]

2 голосов
/ 13 марта 2020

Вы можете использовать stack, который меняет именованный вектор на датафрейм.

temp <- stack(x)
temp
#  values ind
#1      1   a
#2      2   a
#3      3   a
#4      4   b
#5      5   b
#6      6   b
#7      7   c
#8      8   c
#9      9   c

Если вы хотите получить их в виде списка, вы можете split это:

split(temp, temp$ind)

#$a
#  values ind
#1      1   a
#2      2   a
#3      3   a

#$b
#  values ind
#4      4   b
#5      5   b
#6      6   b

#$c
#  values ind
#7      7   c
#8      8   c
#9      9   c

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

purrr::imap(x, ~tibble(Y = .x, name = .y))
1 голос
/ 13 марта 2020

Чтобы избежать факторов в столбцах name, вы можете сделать

res <- Map(`[<-`, lapply(x, to_dataframe), "name", value=names(x))
res
# $a
#   Y name
# 1 1    a
# 2 2    a
# 3 3    a
# 
# $b
#   Y name
# 1 4    b
# 2 5    b
# 3 6    b
# 
# $c
#   Y name
# 1 7    c
# 2 8    c
# 3 9    c

str(res)
# List of 3
# $ a:'data.frame': 3 obs. of  2 variables:
#   ..$ Y   : num [1:3] 1 2 3
#   ..$ name: chr [1:3] "a" "a" "a"
# $ b:'data.frame': 3 obs. of  2 variables:
#   ..$ Y   : num [1:3] 4 5 6
#   ..$ name: chr [1:3] "b" "b" "b"
# $ c:'data.frame': 3 obs. of  2 variables:
#   ..$ Y   : num [1:3] 7 8 9
#   ..$ name: chr [1:3] "c" "c" "c"

или переписать свою функцию и использовать Map.

to_dataframe <- function(x, y) {
  data.frame(Y=x, name=y, stringsAsFactors=FALSE)
}
res <- Map(to_dataframe, x, names(x))
1 голос
/ 13 марта 2020

Вы можете попробовать:

Map(cbind, lapply(x, to_dataframe), name = names(x))

$a
  Y name
1 1    a
2 2    a
3 3    a

$b
  Y name
1 4    b
2 5    b
3 6    b

$c
  Y name
1 7    c
2 8    c
3 9    c
...