如何在dcast()函数中保留NA值?

4
df <- data.frame(x = c(1,1,1,2,2,3,3,3,4,5,5),
                 y = c("A","B","C","A","B","A","B","D","B","C","D"),
                 z = c(3,2,1,4,2,3,2,1,2,3,4))

df_new <- dcast(df, x ~ y, value.var = "z")

如果给定的示例数据中包含NA值,则dcast()函数会保留这些值。但是对于我的数据集,它却无效。因此,该函数将NA转换为零。为什么呢?
如何保留NA值? ml-latest-small.zip
r <- read.csv("ratings.csv")
m <- read.csv("movies.csv")
rm <- merge(ratings, movies, by="movieId")
umr <- dcast(rm, userId ~ title, value.var = "rating", fun.aggregate= sum)

提前感谢您。

1个回答

9
在第一个例子中,没有调用fun.aggregate函数,在第二个情况下,变化在于调用了fun.aggregate函数。根据?dcast文档。
library(reshape2)

fill - 用于填充结构性缺失的值, 默认为将 fun.aggregate 应用于 0 长度向量的结果。

dcast(df, x ~ y, value.var = "z", fun.aggregate = NULL)
# x  A  B  C  D
#1 1  3  2  1 NA
#2 2  4  2 NA NA
#3 3  3  2 NA  1
#4 4 NA  2 NA NA
#5 5 NA NA  3  4

dcast(df, x ~ y, value.var = "z", fun.aggregate = sum)
#  x A B C D
#1 1 3 2 1 0
#2 2 4 2 0 0
#3 3 3 2 0 1
#4 4 0 2 0 0
#5 5 0 0 3 4

请注意,这里每个组合只有一个元素,所以sum将返回相同的值,除非有一个特定的组合不存在,否则它会返回0。这是基于sum的行为。
length(integer(0))
#[1] 0
sum(integer(0))
#[1] 0

sum(NULL)
#[1] 0

如果所有元素都是NA,并且使用na.rm,那么就没有任何元素可以求和,此时也会进入integer(0)模式。

sum(c(NA, NA), na.rm = TRUE)
#[1] 0

如果我们使用来自 `hablar` 的 `sum_`,那么这种行为将被更改为返回 `NA`。
library(hablar)
sum_(c(NA, NA))
#[1] NA

一个选择是在 fun.aggregate 中创建一个条件,使其返回 NA
dcast(df, x ~ y, value.var = "z", 
   fun.aggregate = function(x) if(length(x) == 0) NA_real_ else sum(x, na.rm = TRUE))
#  x  A  B  C  D
#1 1  3  2  1 NA
#2 2  4  2 NA NA
#3 3  3  2 NA  1
#4 4 NA  2 NA NA
#5 5 NA NA  3  4

想了解有关如何创建sum(原始函数)的更多信息,请查看此处的源代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接