当整个组满足条件时对样本进行突变

时间:2020-05-04 08:55:32

标签: r

我有一个大数据集,它分为多个区域。我想标记何时来自给定区域的所有样本都超过给定阈值。如果给定区域的所有样本都高于给定阈值,那么我需要在单独的列中分配一个1值(如果不是给定区域中的所有样本都高于给定阈值,则分配一个2值)。

我意识到我可以使用dplyr中的group_by函数将Zones分配给组,并且我本质上需要将数据突变为新列,但是不确定如何分配依赖于组中所有样本的规则满足一定条件(在这种情况下高于给定阈值)。以下是阈值为1的示例数据帧。

    Zone Value
1  Zone1     1
2  Zone1     2
3  Zone1     2
4  Zone1     1
5  Zone1     2
6  Zone1     4
7  Zone2     3
8  Zone2     1
9  Zone2     2
10 Zone2     2
11 Zone2     1
12 Zone2     1
13 Zone2     2
14 Zone3     1
15 Zone3     2
16 Zone3     1
17 Zone3     0
18 Zone3     1
19 Zone3     1
20 Zone3     0
21 Zone3     0

下面是所需的输出。区域1和2的值为New。这些组中的所有样本都超过阈值1,因此值为1。由于某些样本的值小于1,整个区域3被分配为2。

    Zone Value New.Value
1  Zone1     1         1
2  Zone1     2         1
3  Zone1     2         1
4  Zone1     1         1
5  Zone1     2         1
6  Zone1     4         1
7  Zone2     3         1
8  Zone2     1         1
9  Zone2     2         1
10 Zone2     2         1
11 Zone2     1         1
12 Zone2     1         1
13 Zone2     2         1
14 Zone3     1         2
15 Zone3     2         2
16 Zone3     1         2
17 Zone3     0         2
18 Zone3     1         2
19 Zone3     1         2
20 Zone3     0         2
21 Zone3     0         2

2 个答案:

答案 0 :(得分:1)

这是使用data.table和一些伪数据的示例

# setup 
library(data.table)
set.seed(1)
dt1 <- data.table(
  V1 = sample(letters[1:5], replace = TRUE, size = 15),
  V2 = sample(c(1:4), replace = TRUE, size = 15))

# solution 
dt1[, V3 := all(V2>1), by = V1]

如果您的数据框名为df1,并且您希望将其设为1或2作为值,则解决方案应为

setDT(df1)
df1[, New.value := sum(all(Value>1)) + 1]

答案 1 :(得分:1)

使用dplyr,我们可以检查每个all中的Value >=1是否为Zone并相应地赋值。

library(dplyr)
df %>% group_by(Zone) %>% mutate(New_value = c(2, 1)[all(Value >= 1) + 1])
#Can also use if else. 
#df %>% group_by(Zone) %>% mutate(Value = if(all(Value >= 1)) 1 else 2)

#   Zone  Value
#   <chr> <dbl>
# 1 Zone1     1
# 2 Zone1     1
# 3 Zone1     1
# 4 Zone1     1
# 5 Zone1     1
# 6 Zone1     1
# 7 Zone2     1
# 8 Zone2     1
# 9 Zone2     1
#10 Zone2     1
# … with 11 more rows

并在基数R中:

df$New_value <- with(df, c(2, 1)[ave(Value >= 1, Zone, FUN = all) + 1])