我有一个dataframe,它包含一个dataframe列的每个单元格中的列表。例如,下面是一个测试数据帧。
df <- data.frame(id=1:2)
df$month <- list(c("1","2","3"), c("3","5","7"))
df
我想计算一行中每个列表中的平均差异,并将结果存储为一个新变量,比方说MeanDiff。例如(1,2,3)的平均差为1(2-1)+(3-2)/2))。
我的外部for循环应该是
for (i in 1: nrow(df)){
}
但是,我不知道如何遍历我必须在其上运行函数的行中列表的每个元素,如下所示
Diff = []
Diff[i] = i+1 - i
MeanDiff[i] = Diff/length(Diff)
任何帮助都将不胜感激!此外,这是我的第一篇StackOverflow帖子,我也很感激任何关于提问的元反馈!
发布于 2018-09-06 15:54:29
这里有两个解决方案:
df$diff <- lapply(df$month, function(a) sum(diff(as.numeric(a)))/2)
df
# id month diff
# 1 1 1, 2, 3 1
# 2 2 3, 5, 7 2
这样做的一个问题是,尽管它看起来像一个普通的列,但它并不完全是您所期望的:
df$diff[1]
# [[1]]
# [1] 1
这是单个元素的list
,其中可能需要一个标量(在R的情况下,长度为1的向量)。另一种选择(如JilberUrbina建议的)是在您希望结果长度为1的情况下使用sapply
:
df$diff2 <- sapply(df$month, function(a) sum(diff(as.numeric(a)))/2)
df$diff2[1]
# [1] 1
如果您使用的是tidyverse
工具集(许多人都推荐),请尝试以下方法:
library(dplyr)
library(purrr)
df %>%
mutate(
diff = map(month, ~ sum(diff(as.numeric(.)))/2)
)
# id month diff
# 1 1 1, 2, 3 1
# 2 2 3, 5, 7 2
如果您将其存储在tidyverse
的默认tibble
中,它将如下所示:
tbl_df(df) %>%
mutate(
diff = map(month, ~ sum(diff(as.numeric(.)))/2)
)
# # A tibble: 2 x 3
# id month diff
# <int> <list> <list>
# 1 1 <chr [3]> <dbl [1]>
# 2 2 <chr [3]> <dbl [1]>
虽然这实际上是一回事。如果您计划在一个列中重复存储列表或其他复杂的内容(例如,lm
模型、predict
离子),那么这可能非常方便,而且可能最终是直观的。
发布于 2018-09-06 15:48:57
您可以使用lapply
> lapply(df$month, function(x)
{tmp <- as.numeric(x) # this converts character to numeric
tmp <- sum(diff(tmp))/(length(tmp)-1) # performs calculations
tmp}) # returns output
[[1]]
[1] 1
[[2]]
[1] 2
如果希望输出是向量而不是列表,则为sapply
。
https://stackoverflow.com/questions/52207805
复制相似问题