R 将if_else与data.table.SD结合使用
我需要在R 将if_else与data.table.SD结合使用,r,dplyr,data.table,R,Dplyr,Data.table,我需要在data.table中根据与某些现有列相关的条件集创建新列。但是,我遇到了一些缺少数据的问题。具体来说,每个人都缺少几个数据点。对于某些个人,尽管问卷的全部数据缺失(见下面示例数据中的p==3或4列)。在这种情况下(=问卷的全部数据缺失),我希望data.table在该特定人员的输出中输入NA。我已尝试使用dplyr包中的if_else解决此问题。但是,data.table返回NaN或0,而不是NA,即使一个人的所有数据都丢失(即p列为3或4) 这是我当前的脚本,它仅部分生成所需的输出(
data.table
中根据与某些现有列相关的条件集创建新列。但是,我遇到了一些缺少数据的问题。具体来说,每个人都缺少几个数据点。对于某些个人,尽管问卷的全部数据缺失(见下面示例数据中的p
==3或4列)。在这种情况下(=问卷的全部数据缺失),我希望data.table
在该特定人员的输出中输入NA
。我已尝试使用dplyr
包中的if_else
解决此问题。但是,data.table
返回NaN或0
,而不是NA
,即使一个人的所有数据都丢失(即p
列为3或4)
这是我当前的脚本,它仅部分生成所需的输出(即p
==1或2的正确输出,而不是p
==3或4的正确输出)
如果我理解正确,我建议使用简单的左连接。我认为这是非常严格的,并产生了预期的结果
dt_result <- merge(x = dt
, y = dt[time1 <= 10, .(mean1 = mean(closeness1, na.rm = TRUE)
, sum1 = sum(closeness1, na.rm = TRUE)), by = list(p)]
, by.x = "p"
, by.y = "p"
, all.x = TRUE
)
> dt_result
p time1 closeness1 mean1 sum1
1: 1 12 NA 21.5 43
2: 1 1 NA 21.5 43
3: 1 6 31 21.5 43
4: 1 6 12 21.5 43
5: 1 17 5 21.5 43
6: 2 26 40 NA NA
7: 2 35 18 NA NA
8: 2 39 19 NA NA
9: 2 39 40 NA NA
10: 2 22 NA NA NA
11: 3 NA NA NA NA
12: 3 NA NA NA NA
13: 3 NA NA NA NA
14: 3 NA NA NA NA
15: 3 NA NA NA NA
16: 4 NA NA NA NA
17: 4 NA NA NA NA
18: 4 NA NA NA NA
19: 4 NA NA NA NA
20: 4 NA NA NA NA
dt_result Tiberius,我也可以有冗长的评论或回答,但第一段让人望而生畏。我建议你找到一种减少问题的方法,去掉背景知识,提供简单的数据和简单的预期结果。谢谢你的投入。我更新了这个问题,删除了一些背景知识和一些可能发生的事情的想法。希望现在更清楚。对于dt
样本数据集,您想要的输出是什么?我已经尝试简化我的问题,并为想要的输出添加了脚本means1和sum1是什么,它们是如何计算的?您的示例所需输出仅包含这两个变量的NAs。换言之:如果你还想达到什么样的条件?非常感谢。这有可能简化我的脚本很多,这将是很好的。然而,这让我意识到,我过于简化了我的示例,因为我有几个条件,我需要根据这些条件运行平均值。我已经相应地更新了我的帖子。任何建议都将不胜感激!只需添加另一个联接并更新用于筛选的条件。
# Select rows from original data that were as intended
p12 <- dplyr::filter(dt, p %in% c(1,2))
# Create new data.table with corrected output
p <- c(rep(3, 5), rep(4, 5))
time1 <- as.integer(rep("NA",10))
closeness1 <- as.integer(rep("NA",10))
mean1 <- as.integer(rep("NA",10))
sum1 <- as.integer(rep("NA",10))
dt.des <- data.table::data.table(p, time1, closeness1, mean1, sum1)
# Desired output
dsrd.opt <- dplyr::bind_rows(p12, dt.des)
dsrd.opt
p time1 closeness1 mean1 sum1
1 1 12 NA 21.5 43
2 1 1 NA 21.5 43
3 1 6 31 21.5 43
4 1 6 12 21.5 43
5 1 17 5 21.5 43
6 2 26 40 NaN 0
7 2 35 18 NaN 0
8 2 39 19 NaN 0
9 2 39 40 NaN 0
10 2 22 NA NaN 0
11 3 NA NA NA NA
12 3 NA NA NA NA
13 3 NA NA NA NA
14 3 NA NA NA NA
15 3 NA NA NA NA
16 4 NA NA NA NA
17 4 NA NA NA NA
18 4 NA NA NA NA
19 4 NA NA NA NA
20 4 NA NA NA NA
dt[, c("mean1", "mean2") := .(
dplyr::if_else(sum(is.na(.SD[time1,]))==length(.SD[time1,]) | sum(is.na(.SD[closeness1,]))==length(.SD[closeness1,]),
as.numeric(NA), .SD[time1 <= 10, mean(closeness1, na.rm=TRUE)]),
dplyr::if_else(sum(is.na(.SD[time1,]))==length(.SD[time1,]) | sum(is.na(.SD[closeness1,]))==length(.SD[closeness1,]),
as.numeric(NA), .SD[time1 > 10 & time1 <= 21, mean(closeness1, na.rm=TRUE)])),
by = p, .SDcols = c("time1", "closeness1")]
dsrd.opt
p time1 closeness1 mean1 mean2
1 1 12 NA 21.5 5
2 1 1 NA 21.5 5
3 1 6 31 21.5 5
4 1 6 12 21.5 5
5 1 17 5 21.5 5
6 2 26 40 NaN NaN
7 2 35 18 NaN NaN
8 2 39 19 NaN NaN
9 2 39 40 NaN NaN
10 2 22 NA NaN NaN
11 3 NA NA NA NA
12 3 NA NA NA NA
13 3 NA NA NA NA
14 3 NA NA NA NA
15 3 NA NA NA NA
16 4 NA NA NA NA
17 4 NA NA NA NA
18 4 NA NA NA NA
19 4 NA NA NA NA
20 4 NA NA NA NA
dt_result <- merge(x = dt
, y = dt[time1 <= 10, .(mean1 = mean(closeness1, na.rm = TRUE)
, sum1 = sum(closeness1, na.rm = TRUE)), by = list(p)]
, by.x = "p"
, by.y = "p"
, all.x = TRUE
)
> dt_result
p time1 closeness1 mean1 sum1
1: 1 12 NA 21.5 43
2: 1 1 NA 21.5 43
3: 1 6 31 21.5 43
4: 1 6 12 21.5 43
5: 1 17 5 21.5 43
6: 2 26 40 NA NA
7: 2 35 18 NA NA
8: 2 39 19 NA NA
9: 2 39 40 NA NA
10: 2 22 NA NA NA
11: 3 NA NA NA NA
12: 3 NA NA NA NA
13: 3 NA NA NA NA
14: 3 NA NA NA NA
15: 3 NA NA NA NA
16: 4 NA NA NA NA
17: 4 NA NA NA NA
18: 4 NA NA NA NA
19: 4 NA NA NA NA
20: 4 NA NA NA NA