【问题标题】:ifelse function group in group in RR中组中的ifelse函数组
【发布时间】:2016-07-17 08:03:26
【问题描述】:

我有数据集

ID <- c(1,1,2,2,2,2,3,3,3,3,3,4,4,4)
Eval <- c("A","A","B","B","A","A","A","A","B","B","A","A","A","B")
med <- c("c","d","k","k","h","h","c","d","h","h","h","c","h","k")
df <- data.frame(ID,Eval,med)
> df
    ID Eval med
 1   1    A   c
 2   1    A   d
 3   2    B   k
 4   2    B   k
 5   2    A   h
 6   2    A   h
 7   3    A   c
 8   3    A   d
 9   3    B   h
 10  3    B   h
 11  3    A   h
 12  4    A   c
 13  4    A   h
 14  4    B   k

我尝试创建变量 xy,按 ID 和 Eval 分组。对于每个ID,if Eval = A, and med = "h" or "k",我设置x = 1,其他明智的x = 0if Eval = B and med = "h" or "k",我设置y = 1,其他明智的y = 0。我用我不喜欢的方式,我得到了答案,但似乎不是那么好

df <- data.table(df)
setDT(df)[, count := uniqueN(med) , by = .(ID,Eval)]
setDT(df)[Eval == "A", x:= ifelse(count == 1 & med %in% c("k","h"),1,0), by=ID]
setDT(df)[Eval == "B", y:= ifelse(count == 1 & med %in% c("k","h"),1,0), by=ID]


     ID Eval med count  x  y
 1:  1    A   c     2  0 NA
 2:  1    A   d     2  0 NA
 3:  2    B   k     1 NA  1
 4:  2    B   k     1 NA  1
 5:  2    A   h     1  1 NA
 6:  2    A   h     1  1 NA
 7:  3    A   c     3  0 NA
 8:  3    A   d     3  0 NA
 9:  3    B   h     1 NA  1
10:  3    B   h     1 NA  1
11:  3    A   h     3  0 NA
12:  4    A   c     2  0 NA
13:  4    A   h     2  0 NA
14:  4    B   k     1 NA  1

然后我需要折叠行以获得唯一ID,我不知道如何折叠行,知道吗?

输出

 ID x y
 1  0 0
 2  1 1
 3  0 1
 4  0 1

【问题讨论】:

  • ID 1 的“y”不应该为 0,因为其中只有 NA
  • 是的,你是对的
  • 对于数据的第 11 行,x 不应该是 1,因为 Eval 是 A 而 med 是 h
  • @Maiasaura, line 11, ID 3 with Eval A, 你可以看到它有 Eval "c", "d","h", 它不在组 "h" 和 "k" .所以应该是 0

标签: r if-statement duplicates data.table


【解决方案1】:

我们创建按“ID”分组的“x”和“y”变量,而没有 NA 元素直接将逻辑向量强制为二进制 (as.integer)

df[, x := as.integer(Eval == "A" & count ==1 & med %in% c("h", "k")) , by = ID]

对于“y”也是如此

df[, y := as.integer(Eval == "B" & count ==1 & med %in% c("h", "k")) , by = ID]

总结一下,按“ID”分组后使用any

df[, lapply(.SD, function(x) as.integer(any(x))) , ID, .SDcols = x:y]
#   ID x y
#1:  1 0 0
#2:  2 1 1
#3:  3 0 1
#4:  4 0 1

如果我们需要一种紧凑的方法,而不是分配 (:=),我们根据条件汇总按“ID”、“Eval”分组的输出,然后按“ID”分组,我们检查是否有 @ 987654327@ TRUE 值通过循环遍历.SDcols 中描述的列。

setDT(df)[,  if(any(uniqueN(med)==1 & med %in% c("h", "k"))) {
        .(x= Eval=="A", y= Eval == "B") } else .(x=FALSE, y=FALSE),
     by = .(ID, Eval)][, lapply(.SD, any) , by = ID, .SDcols = x:y]
#  ID     x     y
#1:  1 FALSE FALSE
#2:  2  TRUE  TRUE
#3:  3 FALSE  TRUE
#4:  4 FALSE  TRUE

如果需要,我们可以转换为类似于第一个解决方案中显示的方法的二进制。

【讨论】:

  • 反正我们不使用 setDT(df)[, count := uniqueN(med) , by = .(ID,Eval)],那么如何折叠行呢?
  • @Stat 使用紧凑的方法进行了更新。逻辑向量可以很容易地转换为二进制。
【解决方案2】:

OP的目标...

"我尝试创建变量 x 和 y,按 ID 和 Eval 分组。对于每个 ID,如果 Eval = A,且 med = "h" 或 "k",我设置 x = 1,否则 x = 0 ,如果 Eval = B 和 med = "h" 或 "k",我设置 y = 1,否则 y = 0。[...] 然后我需要折叠行以获得唯一 ID"

可以简化为...

对于每个 ID 和 Eval,如果所有 med 值为 h 或所有 med 值为 k,则标记。

setDT(df) # only do this once
df[, all(med=="k") | all(med=="h"), by=.(ID,Eval)][, dcast(.SD, ID ~ Eval, fun=any)]

   ID     A     B
1:  1 FALSE FALSE
2:  2  TRUE  TRUE
3:  3 FALSE  TRUE
4:  4 FALSE  TRUE

要查看 dcast 正在做什么,请阅读 ?dcast 并尝试仅运行第一部分 df[, all(med=="k") | all(med=="h"), by=.(ID,Eval)]

使用 x 和 y 代替 A 和 B 的更改很简单但不明智(因为不必要的重命名可能会造成混淆,并在有新的 Eval 值时导致额外的工作);并且同上更改为 1/0 而不是 TRUE/FALSE(因为捕获的值实际上是布尔值)。

【讨论】:

  • 这个不错。
【解决方案3】:

这是我的dplyr 解决方案,因为我发现它比data.table 更具可读性。

library(dplyr)
df %>%
  group_by(ID, Eval) %>%
  mutate(
    count = length(unique(med)),
    x = ifelse(Eval == "A" &
                 count == 1 & med %in% c("h", "k"), 1, 0),
    y = ifelse(Eval == "B" &
                 count == 1 & med %in% c("h", "k"), 1, 0)
  )   %>%
  group_by(ID) %>%
  summarise(x1 = max(unique(x)),
            y1 = max(unique(y)))

【讨论】:

    【解决方案4】:

    折叠结果行的单行解决方案:

    df[,lapply(.SD,function(i) {ifelse(1 %in% i,ifelse(!0 %in% i,1,0),0)}),.SDcols=x:y,by=ID]
    
       ID x y
    1:  1 0 0
    2:  2 1 1
    3:  3 0 1
    4:  4 0 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      相关资源
      最近更新 更多