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