dcast не сохраняет тип переменной как символ, ошибка в vapply, когда переменная NA

При попытке изменить данные с помощью resphape2::dcast Я обнаружил ошибку, связанную с NA записей. Пример данных в конце.

Данные изменяются от длинных к широким, но иногда некоторые параметры имеют все NA записи, которые, кажется, вызывают проблему. Или, по крайней мере, я так думаю. Если я удалю какой-либо параметр, как этот, Ammonia в этом примере ошибка исчезает.

В отладке dcast Кажется, это связано с этой строкой:

ordered <- vaggregate(.value = value, .group = overall, 
  .fun = fun.aggregate, ..., .default = fill, .n = n)

что приводит к ошибке:

Error in vapply(indices, fun, .default) : 
values must be type 'character',
but FUN(X[[1]]) result is type 'integer'

Видя, что NA переменная является первой в строке, я думал, aggregate Функция по умолчанию может быть целым числом, даже если весь столбец character, но перемещение этих строк не решило проблему. Единственный способ найти решение - это использовать na.omit, который полностью удаляет этот параметр. Мой ожидаемый результат сохранит любые параметры со всеми NA если возможно. Вторая причина этого заключается в том, что если день / глубина не отбирается, его следует сохранить, и эти записи должны быть ns (без выборки). Есть ли способ, которым я могу решить эту ошибку, не удаляя все NA параметры, которые будут изменены?

Воспроизводимый пример (данные ниже dcast код):

library(reshape2)
dcast(df, station + date + depth ~ parmcode, value.var = "value_qualif", fill="ns")

dcast(na.omit(df), station + date + depth ~ parmcode,
 value.var = "value_qualif", fill="ns") # solves error, but removes parameter completely

Пример данных:

df <- structure(list(station = c("A", "A", "A", "A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A"), date = c("7/2/2018", 
"7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", 
"7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", 
"7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", 
"7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", 
"7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", "7/2/2018", "7/1/2018", 
"7/1/2018", "7/1/2018", "7/1/2018", "7/1/2018", "7/1/2018", "7/1/2018", 
"7/1/2018", "7/1/2018", "7/9/2018", "7/9/2018", "7/9/2018", "7/9/2018", 
"7/9/2018", "7/9/2018", "7/9/2018", "7/9/2018", "7/9/2018", "7/9/2018", 
"7/9/2018", "7/9/2018", "7/9/2018", "7/9/2018", "7/9/2018", "7/9/2018", 
"7/9/2018", "7/9/2018", "7/9/2018", "7/9/2018", "7/9/2018", "7/9/2018", 
"7/9/2018", "7/9/2018", "7/9/2018", "7/9/2018", "7/9/2018", "7/9/2018", 
"7/9/2018", "7/9/2018"), depth = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 
18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 1L, 1L, 1L, 
12L, 12L, 12L, 18L, 18L, 18L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 18L, 
18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L), parmcode = c("CDOM", 
"DENSITY", "DO", "ENTERO", "PH", "TOTAL", "XMS", "TEMP", "SAL", 
"FECAL", "TOTAL", "FECAL", "ENTERO", "CDOM", "XMS", "TEMP", "SAL", 
"PH", "DO", "DENSITY", "DO", "DENSITY", "TOTAL", "FECAL", "PH", 
"CDOM", "XMS", "TEMP", "SAL", "ENTERO", "AMMONIA AS N", "AMMONIA AS N", 
"AMMONIA AS N", "AMMONIA AS N", "AMMONIA AS N", "AMMONIA AS N", 
"AMMONIA AS N", "AMMONIA AS N", "AMMONIA AS N", "TOTAL", "XMS", 
"TEMP", "SAL", "PH", "DO", "DENSITY", "CDOM", "FECAL", "ENTERO", 
"CDOM", "FECAL", "ENTERO", "PH", "DO", "TEMP", "XMS", "TOTAL", 
"DENSITY", "SAL", "TOTAL", "FECAL", "ENTERO", "XMS", "TEMP", 
"SAL", "PH", "DO", "DENSITY", "CDOM"), value_qualif = c(NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, "<2", "<2", "<2", "1.3", "69.67", 
"16.6", "33.7", "8.1", "7.6", "24.622", "5.5", "25.279", "<2", 
"<2", "7.8", "1.38", "72.96", "13.2", "33.61", "<2", NA, NA, 
NA, NA, NA, NA, NA, NA, NA, "<2", "77.82", "20.8", "33.72", "8.2", 
"8.8", "23.58", "1.01", "<2", "<2", "1.78", "<2", "<2", "8", 
"6.5", "13.5", "67.19", "2e", "25.197", "33.58", "2e", "2e", 
"<2", "75.53", "12.9", "33.61", "7.9", "5.5", "25.34", "1.77"
)), class = "data.frame", row.names = c(NA, -69L))

Некоторые вопросы, связанные с тангенциальной связью, которые не отвечают на мой вопрос: значения POSIXct становятся числовыми в rescast2 dcast и Ошибка с пользовательской статистической функцией для вызова cast() в R reshape2

С использованием na.omit мой вывод:

  station     date depth CDOM DENSITY  DO ENTERO FECAL  PH   SAL TEMP TOTAL   XMS
1       A 7/2/2018    12  1.3  24.622 7.6     <2    <2 8.1  33.7 16.6    <2 69.67
2       A 7/2/2018    18 1.38  25.279 5.5     <2    <2 7.8 33.61 13.2    <2 72.96
3       A 7/9/2018     1 1.01   23.58 8.8     <2    <2 8.2 33.72 20.8    <2 77.82
4       A 7/9/2018    12 1.78  25.197 6.5     <2    <2   8 33.58 13.5    2e 67.19
5       A 7/9/2018    18 1.77   25.34 5.5     <2    2e 7.9 33.61 12.9    2e 75.53

Ожидаемый результат без использования na.omit является:

  station     date depth AMMONIA CDOM  DENSITY  DO  ENTERO FECAL  PH   SAL TEMP TOTAL   XMS
1       A 7/2/2018     1    ns    ns      ns    ns     ns    ns   ns    ns   ns    ns    ns
2       A 7/2/2018    12    ns    1.3   24.622  7.6    <2    <2  8.1  33.7 16.6    <2 69.67
3       A 7/2/2018    18    ns    1.38  25.279  5.5    <2    <2  7.8 33.61 13.2    <2 72.96
4       A 7/9/2018     1    ns    1.01  23.58   8.8    <2    <2  8.2 33.72 20.8    <2 77.82
5       A 7/9/2018    12    ns    1.78  25.197  6.5    <2    <2    8 33.58 13.5    2e 67.19
6       A 7/9/2018    18    ns    1.77  25.34   5.5    <2    2e  7.9 33.61 12.9    2e 75.53

1 ответ

Решение

Фактическая проблема заключается в том, что все параметры имеют только одно значение для каждой тройки (станция, дата, глубина), за исключением AMMONIA AS N, который имеет три NA записей.

Например,

dcast(df, station + date + depth ~ parmcode, value.var = "value_qualif")
# Aggregation function missing: defaulting to length
#   station     date depth AMMONIA AS N CDOM DENSITY DO ENTERO FECAL PH SAL TEMP TOTAL XMS
# 1       A 7/1/2018     1            3    0       0  0      0     0  0   0    0     0   0
# 2       A 7/1/2018    12            3    0       0  0      0     0  0   0    0     0   0
# 3       A 7/1/2018    18            3    0       0  0      0     0  0   0    0     0   0
# 4       A 7/2/2018     1            0    1       1  1      1     1  1   1    1     1   1
# 5       A 7/2/2018    12            0    1       1  1      1     1  1   1    1     1   1
# 6       A 7/2/2018    18            0    1       1  1      1     1  1   1    1     1   1
# 7       A 7/9/2018     1            0    1       1  1      1     1  1   1    1     1   1
# 8       A 7/9/2018    12            0    1       1  1      1     1  1   1    1     1   1
# 9       A 7/9/2018    18            0    1       1  1      1     1  1   1    1     1   1

Как только мы удалим дублирующиеся строки, все будет работать гладко

dcast(df[!duplicated(df), ], station + date + depth ~ parmcode, value.var = "value_qualif")
#   station     date depth AMMONIA AS N CDOM DENSITY   DO ENTERO FECAL   PH   SAL TEMP TOTAL   XMS
# 1       A 7/1/2018     1         <NA> <NA>    <NA> <NA>   <NA>  <NA> <NA>  <NA> <NA>  <NA>  <NA>
# 2       A 7/1/2018    12         <NA> <NA>    <NA> <NA>   <NA>  <NA> <NA>  <NA> <NA>  <NA>  <NA>
# 3       A 7/1/2018    18         <NA> <NA>    <NA> <NA>   <NA>  <NA> <NA>  <NA> <NA>  <NA>  <NA>
# 4       A 7/2/2018     1         <NA> <NA>    <NA> <NA>   <NA>  <NA> <NA>  <NA> <NA>  <NA>  <NA>
# 5       A 7/2/2018    12         <NA>  1.3  24.622  7.6     <2    <2  8.1  33.7 16.6    <2 69.67
# 6       A 7/2/2018    18         <NA> 1.38  25.279  5.5     <2    <2  7.8 33.61 13.2    <2 72.96
# 7       A 7/9/2018     1         <NA> 1.01   23.58  8.8     <2    <2  8.2 33.72 20.8    <2 77.82
# 8       A 7/9/2018    12         <NA> 1.78  25.197  6.5     <2    <2    8 33.58 13.5    2e 67.19
# 9       A 7/9/2018    18         <NA> 1.77   25.34  5.5     <2    2e  7.9 33.61 12.9    2e 75.53

dcast(df[!duplicated(df), ], station + date + depth ~ parmcode, value.var = "value_qualif", fill = "ns")
#   station     date depth AMMONIA AS N CDOM DENSITY  DO ENTERO FECAL  PH   SAL TEMP TOTAL   XMS
# 1       A 7/1/2018     1           ns   ns      ns  ns     ns    ns  ns    ns   ns    ns    ns
# 2       A 7/1/2018    12           ns   ns      ns  ns     ns    ns  ns    ns   ns    ns    ns
# 3       A 7/1/2018    18           ns   ns      ns  ns     ns    ns  ns    ns   ns    ns    ns
# 4       A 7/2/2018     1           ns   ns      ns  ns     ns    ns  ns    ns   ns    ns    ns
# 5       A 7/2/2018    12           ns  1.3  24.622 7.6     <2    <2 8.1  33.7 16.6    <2 69.67
# 6       A 7/2/2018    18           ns 1.38  25.279 5.5     <2    <2 7.8 33.61 13.2    <2 72.96
# 7       A 7/9/2018     1           ns 1.01   23.58 8.8     <2    <2 8.2 33.72 20.8    <2 77.82
# 8       A 7/9/2018    12           ns 1.78  25.197 6.5     <2    <2   8 33.58 13.5    2e 67.19
# 9       A 7/9/2018    18           ns 1.77   25.34 5.5     <2    2e 7.9 33.61 12.9    2e 75.53

В качестве альтернативы, вы можете запустить

dcast(df, station + date + depth ~ parmcode, value.var = "value_qualif", 
      fill = NA_character_, fun.aggregate = head, n = 1)
#   station     date depth AMMONIA AS N CDOM DENSITY   DO ENTERO FECAL   PH   SAL TEMP TOTAL   XMS
# 1       A 7/1/2018     1         <NA> <NA>    <NA> <NA>   <NA>  <NA> <NA>  <NA> <NA>  <NA>  <NA>
# 2       A 7/1/2018    12         <NA> <NA>    <NA> <NA>   <NA>  <NA> <NA>  <NA> <NA>  <NA>  <NA>
# 3       A 7/1/2018    18         <NA> <NA>    <NA> <NA>   <NA>  <NA> <NA>  <NA> <NA>  <NA>  <NA>
# 4       A 7/2/2018     1         <NA> <NA>    <NA> <NA>   <NA>  <NA> <NA>  <NA> <NA>  <NA>  <NA>
# 5       A 7/2/2018    12         <NA>  1.3  24.622  7.6     <2    <2  8.1  33.7 16.6    <2 69.67
# 6       A 7/2/2018    18         <NA> 1.38  25.279  5.5     <2    <2  7.8 33.61 13.2    <2 72.96
# 7       A 7/9/2018     1         <NA> 1.01   23.58  8.8     <2    <2  8.2 33.72 20.8    <2 77.82
# 8       A 7/9/2018    12         <NA> 1.78  25.197  6.5     <2    <2    8 33.58 13.5    2e 67.19
# 9       A 7/9/2018    18         <NA> 1.77   25.34  5.5     <2    2e  7.9 33.61 12.9    2e 75.53

Смотрите этот ответ относительно NA_character_,

Другие вопросы по тегам