#r #date #sum #apply #lubridate
#r #Дата #сумма #применить #lubridate
Вопрос:
В приведенном ниже примере, почему A не равно B ? Проблема связана со столбцом даты, поскольку AA = BB, но я не могу понять почему…
library(lubridate)
MM=data.frame(ID=1:3,Date=ymd(c("2019-11-07","2019-11-07","2019-11-13")),X=c(-1,1,1),Y=c(1,-1,-1))
A=apply(MM,2,function(x) sum(x>0))
B=colSums(MM>0)
A
# ID Date X Y
# 3 3 0 0
B
# ID Date X Y
# 3 3 2 1
AA=apply(MM[,-2],2,function(x) sum(x>0))
BB=colSums(MM[,-2]>0)
AA
# ID X Y
# 3 2 1
BB
# ID X Y
# 3 2 1
R версия 4.0.3 (2020-10-10)
Ответ №1:
Это потому apply
, что перед применением функции к каждому столбцу сначала преобразуется data.frame в матрицу.
Поэтому:
> as.matrix(MM)
ID Date X Y
[1,] "1" "2019-11-07" "-1" " 1"
[2,] "2" "2019-11-07" " 1" "-1"
[3,] "3" "2019-11-13" " 1" "-1"
Все преобразуется в символ.
В частности, вы можете видеть, что:
> " 1" > 0
[1] FALSE
> "1" > 0
[1] TRUE
Это потому, что 0 преобразуется в char .
«0» стоит перед «1» в алфавитном порядке, потому что символ 0 сравнивается с пробелом вместо символа «1».
Порядок строк определяется путем сравнения символа за символом 1 на 1. (это та же причина, почему "10" > "9"
FALSE
, потому 1
что в алфавитном порядке перед 9
).
> sort(c("0", " 1"))
[1] " 1" "0"
> sort(c("0", "1"))
[1] "0" "1"
Как следствие:
> as.matrix(MM)>0
ID Date X Y
[1,] TRUE TRUE FALSE FALSE
[2,] TRUE TRUE FALSE FALSE
[3,] TRUE TRUE FALSE FALSE
colSums
этого не делает.
Вы можете получить тот же результат colSums
, что и при выполнении:
> apply(MM>0, 2, sum)
ID Date X Y
3 3 2 1
Комментарии:
1. Напротив,
MM > 0
работает с целочисленными значениями, лежащимиDate
в основе объекта.2.
sapply
этого тоже не делает, поэтомуsapply(MM, function(x) sum(x>0))
работает по назначению.3. И все приведено к символьной матрице (не «дата-время»).
4. Хорошо! Спасибо! Но в чем тестируется
as.matrix(MM)[1] > 0
? Почему"1">0
возвращает TRUE, а" 1">0
не нет?