R: Распакуйте функцию, которая возвращает несколько объектов в несколько столбцов кадра данных. - PullRequest
0 голосов
/ 12 сентября 2018

Надеюсь, я просто объясню проблему:

У меня есть функция следующей формы, которая возвращает два представляющих интерес значения.

return_network <- function(team_id){
   ... [ do something to produce adjacency matrix and network density measures] 

  g <- graph.adjacency(co_occur, weighted=TRUE, mode ='undirected')
  g <- simplify(g)

  return(c(weighted_network_density, g))

Затем я хочу перебрать столбец в кадре данных, применить вышеуказанную функцию и распаковать его в два столбца. Я пробовал следующее:

team_measures[, c('weighted_network_density', 'graph_object')]  <- apply(team_measures[, "team_id", drop=F], 1, return_network)

Тем не менее, я получаю предупреждение:

Warning message:
In `[<-.data.frame`(`*tmp*`, , c("weighted_network_density", "graph_object"),  :
  provided 429 variables to replace 2 variables

И полученный фрейм данных полон чепухи.

1 Ответ

0 голосов
/ 12 сентября 2018

Вот предположение о проблеме: выходные данные каждого шага в apply связаны в виде столбцов, даже если вы применяете их к строкам, поэтому результат транспонируется так, как ожидалось (по крайней мере, я). Мой простой пример ниже не воспроизводит вашу ошибку, так как это так. Если у нас есть эти data.frame:

df <- data.frame(dog = c(1,2,3), cat = c(4,5,6), fish = c(7,8,9))
df
  dog cat fish
1   1   4    7
2   2   5    8
3   3   6    9

Если мы применяем функцию по строкам, которая возвращает 2 значения, мы получаем матрицу с 2 строками:

apply(df, 1, function(x) c(x['dog'], x['cat']))
    [,1] [,2] [,3]
dog    1    2    3
cat    4    5    6

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

df2 <- df
df2[,c('cat', 'fish')] <- apply(df, 1, function(x) c(x['dog'], x['cat']))
df2
  dog cat fish
1   1   1    5
2   2   4    3
3   3   2    6

Если мы преобразуем результат в data.frame перед его назначением (что может произойти где-то в вашем коде), мы получим похожую ошибку:

df2[,c('cat', 'fish')] <- as.data.frame(apply(df, 1, function(x) c(x['dog'], x['cat'])))
Error in `[<-.data.frame`(`*tmp*`, , c("cat", "fish"), value = list(V1 = c(1,  : 
  replacement element 1 has 2 rows, need 3

Транспонирование результата перед передачей в нем заглушает ошибку и приводит к правильному размещению данных в данных:

df2[,c('cat', 'fish')] <- as.data.frame(t(apply(df, 1, function(x) c(x['dog'], x['cat']))))
df2
  dog cat fish
1   1   1    4
2   2   2    5
3   3   3    6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...