Я пытаюсь заставить столбец использовать имена в нескольких разделенных фреймах данных, а затем применить функцию ко всем фреймам данных? (неравные длины) Я получаю сообщение об ошибке, встроенное в приведенный ниже код. Могу ли я работать дальше?
# sample dataset below
ID <- c("SB1","SB2","SB3","SB4","SB1","SB1","SB2","SB4","SB2", "SB1")
z <- c("A","B","C","D","E","A","B","C","D","D")
x <- 1:2
y <- 1:10
n <- max(length(x), length(y))
year <- c(1999,1999,1999,1999,2000,2001,2000,2001,2001,2002)
length(x) <- n
length(y) <- n
length(z) <- n
length(year) <- n
sitebyspec <- cbind(ID,x,y,z,year)
sitebyspec <- as.data.frame(sitebyspec)
# my process (split df by year, force ID column to rownames)
sitebyspec.split <- split(sitebyspec, (sitebyspec$year)) # split based on season
as.data.frame(sitebyspec.split) %>% remove_rownames %>% column_to_rownames(var = "ID")
## Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, : arguments imply differing number of rows: 4, 2, 3, 1
# my next step if this worked ...
sitebyspec.split %>%
sitebyspec.split[,c(1:3)] %>%
map(~ contribdiv(., "richness")) %>%
map(summary)
Могу ли я интегрировать столбец с именами на этом последнем этапе?
С измененными данными (см. Ниже) вот решение.
Возможно, основная проблема заключается в ваших данных. Как и предусмотрено, в вашем столбце x
много НАП, где я предполагаю, что x
должен был переработать сам себя. Тогда vegan::contribdiv()
требует как минимум двух измерений, а вы предоставляете только одну строку в своих данных. Кроме того, он требует числового значения и может применяться только к столбцам 1:2
. В вашем коде с as.data.frame(sitebyspec.split)
вы пытаетесь превратить список в фрейм данных, что, я не думаю, вам нужно, и это приводит к ошибке.
Во-первых, используйте lapply()
для преобразования столбца ID
в имена строк.
sitebyspec.split <- lapply(sitebyspec.split, function(x) "rownames<-"(x, x[, 1])[, -1])
Во-вторых, используйте lapply()
, чтобы применить вашу функцию к списку.
library(vegan)
sitebyspec.result <- lapply(sitebyspec.split, function(x) contribdiv(x[, 1:2], "richness"))
Результат
> sitebyspec.result
$`1999`
alpha beta gamma
SB1 0.6666667 0 0.6666667
SB2 0.6666667 0 0.6666667
SB3 0.6666667 0 0.6666667
$`2000`
alpha beta gamma
SB4 1 0 1
SB1 1 0 1
$`2001`
alpha beta gamma
SB1 0.6666667 0 0.6666667
SB2 0.6666667 0 0.6666667
SB4 0.6666667 0 0.6666667
$`2002`
alpha beta gamma
SB2 1 0 1
SB1 1 0 1
Данные
sitebyspec <- data.frame(ID=c("SB1", "SB2", "SB3", "SB4", "SB1", "SB1", "SB2", "SB4", "SB2", "SB1"),
x=1:2,
y=1:10,
z=c("A", "B", "C", "D", "E", "A", "B", "C", "D", "D"),
year=c(1999, 1999, 1999, 2000, 2001, 2000, 2001, 2001, 2002, 2002))
Поскольку объектом является list
, мы можем пройти через list
с помощью map
, а затем применить функции в сообщении OP.
sitebyspec.split %>%
map(~ .x %>%
remove_rownames %>%
column_to_rownames(var = "ID"))
#$`1999`
# x y z year
#SB1 1 1 A 1999
#SB2 2 2 B 1999
#SB3 1 3 C 1999
#$`2000`
# x y z year
#SB4 2 4 D 2000
#SB1 2 6 A 2000
#$`2001`
# x y z year
#SB1 1 5 E 2001
#SB2 1 7 B 2001
#SB4 2 8 C 2001
#$`2002`
# x y z year
#SB2 1 9 D 2002
#SB1 2 10 D 2002
Функция contribdv
может применяться в той же цепочке
library(vegan)
sitebyspec.split %>%
map(~ .x %>%
remove_rownames %>%
column_to_rownames(var = "ID") %>%
select(1:2) %>%
contribdiv(., "richness"))
#$`1999`
# alpha beta gamma
#SB1 0.6666667 0 0.6666667
#SB2 0.6666667 0 0.6666667
#SB3 0.6666667 0 0.6666667
#$`2000`
# alpha beta gamma
#SB4 1 0 1
#SB1 1 0 1
#$`2001`
# alpha beta gamma
#SB1 0.6666667 0 0.6666667
#SB2 0.6666667 0 0.6666667
#SB4 0.6666667 0 0.6666667
#$`2002`
# alpha beta gamma
#SB2 1 0 1
#SB1 1 0 1
ПРИМЕЧАНИЕ: OP создал столбцы 'x', 'y' как factor
s, вместо этого он должен быть numeric
sitebyspec <- structure(list(ID = structure(c(1L, 2L, 3L, 4L, 1L, 1L, 2L, 4L,
2L, 1L), .Label = c("SB1", "SB2", "SB3", "SB4"), class = "factor"),
x = c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), y = 1:10,
z = structure(c(1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 4L), .Label = c("A",
"B", "C", "D", "E"), class = "factor"), year = c(1999, 1999,
1999, 2000, 2001, 2000, 2001, 2001, 2002, 2002)), .Names = c("ID",
"x", "y", "z", "year"), row.names = c(NA, -10L), class = "data.frame")
Рассмотрим by
базы R. В отличие от split
, вы можете передать функцию непосредственно в подмножество фреймов данных:
proc_df <- function(df) df %>% remove_rownames %>% column_to_rownames(var = "ID")
df_list <- by(sitebyspec, sitebyspec$year, proc_df)
df_list
# sitebyspec$year: 1999
# x y z year
# SB1 1 1 A 1999
# SB2 2 2 B 1999
# SB3 1 3 C 1999
# SB4 2 4 D 1999
# ----------------------------------------------------------------------------
# sitebyspec$year: 2000
# x y z year
# SB1 1 5 E 2000
# SB2 1 7 B 2000
# ----------------------------------------------------------------------------
# sitebyspec$year: 2001
# x y z year
# SB1 2 6 A 2001
# SB4 2 8 C 2001
# SB2 1 9 D 2001
# ----------------------------------------------------------------------------
# sitebyspec$year: 2002
# x y z year
# SB1 2 10 D 2002
А для расширенной функции
proc_df <- function(df) {
tryCatch({df %>%
remove_rownames %>%
column_to_rownames(var = "ID") %>%
select(1:2) %>%
contribdiv(., "richness")
}, error = function(e) NA)
}
df_list <- by(sitebyspec, sitebyspec$year, proc_df)
Спасибо за сообщение! Это интересный способ сделать это - я этого раньше не видел. Когда я делаю это с моими фактическими данными, я получаю сообщение об ошибке «Ошибка в rowSums (comm): 'x' должно быть числовым». Все столбцы числовые. есть идеи, в чем может быть проблема?
Не знаю, почему это происходит, пока не увижу полные данные. Работает ли указанное выше на опубликованном образце? Если да, то это проблема данных с фактическими данными.
Здравствуйте, код не работает с образцами данных.
См. Вызов обновления в tryCatch
, где при любых ошибках возвращается NA
в списке. Возможно, одна из групп год не может быть запущена в contribdiv
.
Сейчас я заставляю это работать, но на последнем шаге (шаге сопоставления) продолжает появляться ошибка. Ошибка в min (which (comm [, i] == 1)): max (which (comm [, i] == 1)): результат будет слишком длинным вектором
Какой шаг отображения? При использовании tryCatch
не должно возникать никаких ошибок.
Между тем,
by
примерно эквивалентенsplit
+lapply
!