使用 apply() 但得到 class 列表答案
Using apply() but getting class list answer
我在 data.frame
中有一系列列,我想获取其中的最后一个值,不包括任何 NA。我用来完成这项工作的功能是
last_value <- function(x) tail(x[!is.na(x)], 1)
我正在使用 apply()
在 13 列中为每个观察(按行)运行此函数。
df$LastVal<-apply(df[,c(116, 561, 1006, 1451, 1896, 2341, 2786, 3231,
3676, 4121, 4566, 5011, 5456)], 1, FUN=last_value)
我的问题是输出结果为 5336(总观察值)的列表,而不仅仅是按行排列的最后一个值的向量。答案似乎就在那里,但还是以列表的形式出现。我以前用过这个功能,效果很好。当我 str()
我的专栏时,它们都是整数。
如果没有值而只有 NA,这个函数会不会出错?
我应该补充一点,当我 unlist()
新变量时,我得到一个错误 "replacement has 4649 rows, data has 5336",所以我认为这可能与 NAs 有关。
您可以将您的函数包含在选择中。
例子
df <- as.data.frame(matrix(1:12, 3, 4))
> df
V1 V2 V3 V4
1 1 4 7 10
2 2 5 8 11
3 3 6 9 12
last_value <- function(x) tail(x[!is.na(x)], 1)
> df[, last_value(c(3, 4))] # selects last column
[1] 10 11 12
测试 NA
。
df[2, 4] <- NA
> df[, last_value(c(3, 4))]
[1] 10 NA 12
如果您需要 apply()
方法,请使用@Rui Barradas 解释清楚的答案。如果您依赖速度,请考虑两种解决方案的基准:
Unit: microseconds
expr min lq mean median uq max neval cld
apply(df, 1, last_value) 166.095 172.6005 182.09241 177.449 188.2925 257.179 100 b
df[, last_value(c(3, 4))] 32.147 33.4230 36.12764 34.699 35.5920 131.396 100 a
Apropos——按列使用sapply()
。
> sapply(df[, c(3, 4)], FUN=last_value)
V3 V4
9 12
首先,您需要查看函数 last_value
的输出是什么,因为您用一行 NA
值定义了它。
last_value <- function(x) tail(x[!is.na(x)], 1)
df <- matrix(1:24, 4)
df[2, ] <- NA
df <- as.data.frame(df)
apply(df, 1, last_value)
#[[1]]
#V6
#21
#
#[[2]]
#named integer(0)
#
#[[3]]
#V6
#23
#
#[[4]]
#V6
#24
问题是该列表的第二个成员的长度为零。也就是说unlist
解决不了问题
您必须测试长度为零的值。
last_value <- function(x) {
y <- tail(x[!is.na(x)], 1)
if(length(y) == 0) NA else y
}
apply(df, 1, last_value)
#[1] 21 NA 23 24
我在 data.frame
中有一系列列,我想获取其中的最后一个值,不包括任何 NA。我用来完成这项工作的功能是
last_value <- function(x) tail(x[!is.na(x)], 1)
我正在使用 apply()
在 13 列中为每个观察(按行)运行此函数。
df$LastVal<-apply(df[,c(116, 561, 1006, 1451, 1896, 2341, 2786, 3231,
3676, 4121, 4566, 5011, 5456)], 1, FUN=last_value)
我的问题是输出结果为 5336(总观察值)的列表,而不仅仅是按行排列的最后一个值的向量。答案似乎就在那里,但还是以列表的形式出现。我以前用过这个功能,效果很好。当我 str()
我的专栏时,它们都是整数。
如果没有值而只有 NA,这个函数会不会出错?
我应该补充一点,当我 unlist()
新变量时,我得到一个错误 "replacement has 4649 rows, data has 5336",所以我认为这可能与 NAs 有关。
您可以将您的函数包含在选择中。
例子
df <- as.data.frame(matrix(1:12, 3, 4))
> df
V1 V2 V3 V4
1 1 4 7 10
2 2 5 8 11
3 3 6 9 12
last_value <- function(x) tail(x[!is.na(x)], 1)
> df[, last_value(c(3, 4))] # selects last column
[1] 10 11 12
测试 NA
。
df[2, 4] <- NA
> df[, last_value(c(3, 4))]
[1] 10 NA 12
如果您需要 apply()
方法,请使用@Rui Barradas 解释清楚的答案。如果您依赖速度,请考虑两种解决方案的基准:
Unit: microseconds
expr min lq mean median uq max neval cld
apply(df, 1, last_value) 166.095 172.6005 182.09241 177.449 188.2925 257.179 100 b
df[, last_value(c(3, 4))] 32.147 33.4230 36.12764 34.699 35.5920 131.396 100 a
Apropos——按列使用sapply()
。
> sapply(df[, c(3, 4)], FUN=last_value)
V3 V4
9 12
首先,您需要查看函数 last_value
的输出是什么,因为您用一行 NA
值定义了它。
last_value <- function(x) tail(x[!is.na(x)], 1)
df <- matrix(1:24, 4)
df[2, ] <- NA
df <- as.data.frame(df)
apply(df, 1, last_value)
#[[1]]
#V6
#21
#
#[[2]]
#named integer(0)
#
#[[3]]
#V6
#23
#
#[[4]]
#V6
#24
问题是该列表的第二个成员的长度为零。也就是说unlist
解决不了问题
您必须测试长度为零的值。
last_value <- function(x) {
y <- tail(x[!is.na(x)], 1)
if(length(y) == 0) NA else y
}
apply(df, 1, last_value)
#[1] 21 NA 23 24