r-根据因子查找具有不完备集的行,然后用NA替换不完备集存在的值

  • 本文关键字:不完备 然后 NA 替换 存在 查找 r tidyr plyr
  • 更新时间 :
  • 英文 :


我无法解决这个问题。

我有一个不完整的数据集(许多行和变量(,其中有一个因素指定所有其他变量是前变量还是后变量。我需要获得所有变量的汇总统计信息,包括pre-and-post值不是NA的行

我试图找到一种方法,如果每个变量的集合都不完整,用NA替换现有值。

以下是我试图实现的一个简单示例:

df = data.frame(
id = c(1,1,2,2),
myfactor = as.factor(c(1,2,1,2)),
var2change = c(10,10,NA,20),
var3change = c(5,10,15,20),
var4change = c(NA,2,3,8)
)

这导致:

id myfactor var2change var3change var4change
1  1        1         10          5         NA
2  1        2         10         10          2
3  2        1         NA         15          3
4  2        2         20         20          8

我想要的输出是:

id myfactor var2change var3change var4change
1  1        1         10          5         NA
2  1        2         10         10         NA
3  2        1         NA         15          3
4  2        2         NA         20          8

我要处理的变量不止一个,而且每个变量的集合都是不完整的。我觉得这可以通过巧妙地使用plyr/tidyr包中的现有功能来实现,但我找不到一种优雅的方法来将这些概念应用于我的问题。

如有任何帮助,我们将不胜感激。

您可以按id分组,如果任何值中有NA,则用NA替换所有值。要将一个函数应用于多个列,我们使用across

library(dplyr)
df %>%
group_by(id) %>%
mutate(across(starts_with('var'), ~if(any(is.na(.))) NA else .))
#for dplyr < 1.0.0 we can use `mutate_at`
#mutate_at(vars(starts_with('var')), ~if(any(is.na(.))) NA else .)
#     id myfactor var2change var3change var4change
#  <dbl> <fct>         <dbl>      <dbl>      <dbl>
#1     1 1                10          5         NA
#2     1 2                10         10         NA
#3     2 1                NA         15          3
#4     2 2                NA         20          8

有一个分组变量(group(和时间变量(myfactor(会有所帮助。然后,您可以使用dplyr进行一些财务处理以创建所需的变量。

library(dplyr)
df = data.frame(
group = rep(c(1,2), each = 2),
myfactor = as.factor(c(1,2,1,2)),
var2change = c(10,10,NA,20)
)
df %>% group_by(group) %>%
mutate(var3change = all(!is.na(var2change)),
var4change = if_else(var3change, var2change, as.numeric(NA)))

我假设您拥有的数据集是有序的,因此每对观测都按其行索引进行分组。

默认情况下,如果mean()函数的任何输入是NA,它将返回一个NA。因此,这是使用dplyr按组获得NA的一种巧妙方法。

library(dplyr)
df = data.frame(
myfactor = as.factor(c(1,2,1,2)),
var2change = c(10,10,NA,20)
)
# 1 Create ID variable to group rows in pairs
id = c()
j = 0
for (i in 1:length(df$var2change)){
k = floor(j/2)
id = c(id, k)
j = j + 1
}
df$id = id
# Set all variables within group to NA if one of them is
df = df %>% 
group_by(id) %>%
mutate(var_changed = mean(var2change)) 

如果数据中有一个显式ID变量,则可以替换此解决方案的第一部分。

编辑:对多个变量执行此操作(基于问题的更改(:

df = data.frame(
id = c(1,1,2,2),
myfactor = as.factor(c(1,2,1,2)),
var2change = c(10,10,NA,20),
var3change = c(5,10,15,20),
var4change = c(NA,2,3,8)
)
for (col in 2:4) {
col = paste0("var", col, "change")
df = df %>% 
group_by(id) %>%
mutate(new_col = mean(get(col))) 
df[["new_col"]] = ifelse(is.na(df["new_col"]), NA, df[[col]])
df[col] = NULL
names(df)[names(df) == "new_col"] <- col
}

如果速度是个问题,可以通过将group_by移动到环路之外来加快速度

最新更新