0

我有一个大型数据集,包含约 100 行和 +1000 列。我的一些参与者(行)在某些变量(列)中输入的数据中出现错误,我想自动更正这些错误。

这是一个具有少量行和列的可重现示例:

d <- tibble(nb = c(33, 54, 72),
            C1_1_66 = c(160, 7, 72),
            C1_1_77 = c(270, 18, 25),
            C1_1_88 = c(120, 5, 46),
            C1_1_99 = c(87, NA, NA),
            C1_2_66 = c(NA, 1, NA),
            C1_2_77 = c(NA, 45, NA),
            C1_2_88 = c(NA, NA, 77),
            C1_2_99 = c(2, NA, NA),
            C2_1_66 = c(120, NA, 90),
            C2_1_77 = c(170, NA, 102),
            C2_1_88 = c(120, NA, NA),
            C2_1_99 = c(230, NA, NA))
# A tibble: 3 x 13
     nb C1_1_66 C1_1_77 C1_1_88 C1_1_99 C1_2_66 C1_2_77 C1_2_88 C1_2_99 C2_1_66 C2_1_77 C2_1_88 C2_1_99
  <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1    33     160     270     120      87      NA      NA      NA       2     120     170     120     230
2    54       7      18       5      NA       1      45      NA      NA      NA      NA      NA      NA
3    72      72      25      46      NA      NA      NA      77      NA      90     102      NA      NA

本质上,我想要的是:

d <- d %>%
  mutate(C1_1_99 = C1_1_88 + C1_1_99, C1_1_88 = NA)

# A tibble: 3 x 13
     nb C1_1_66 C1_1_77 C1_1_88 C1_1_99 C1_2_66 C1_2_77 C1_2_88 C1_2_99 C2_1_66 C2_1_77 C2_1_88 C2_1_99
  <dbl>   <dbl>   <dbl> <lgl>     <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1    33     160     270 NA          207      NA      NA      NA       2     120     170     120     230
2    54       7      18 NA           NA       1      45      NA      NA      NA      NA      NA      NA
3    72      72      25 NA           NA      NA      NA      77      NA      90     102      NA      NA
> 

即,从以_88 结尾的列中删除内容并将其添加到以_99 结尾的相应列中,并从_88 变量中删除内容。重要的是,每个_88 都添加到其对应的_99 中(例如,在C1_1、C1_2、C1_3、C2_1、C2_2 等中的编码之后......一直到C17)。但我希望它自动应用于以 _88 和 _99 结尾的所有变量。_88 列在所有行中都设置为 NA 并不是一个大问题(我正在处理一个子集数据框,其中仅包含对 _88 变量产生错误的参与者),尽管它不是很优雅。

不知道如何解决这个问题。我尝试了这样的事情,但没有成功:

f88 <- function(df, n){
  varname <- paste('C[0-9]_[0-9]_99')
  df %>%
    mutate(!!varname := 'C[0-9]_[0-9]_88' + 'C[0-9]_[0-9]_99')
}

for(i in 2:13) {
  unknown_t <- f88(df=d, n=i)
}

有任何想法吗?提前谢谢了。

4

2 回答 2

0

一种tidyverse方法是将其变成长格式,然后添加列,然后再次将其重新整形为宽格式。

d %>%
  pivot_longer(-nb,
               names_pattern = "(.+)(\\d{2})",
               names_to = c("prefix", ".value")) %>% 
  mutate(`99` = `88` + `99`,
         `88` = NA) %>% 
  pivot_wider(names_from = "prefix",
              values_from = c("66", "77", "88", "99"),
              names_sep = "-") %>% 
  setNames(nm = sub("(.*)-(.*)", "\\2\\1", names(.))) # repair the names
于 2020-03-06T15:06:38.933 回答
0

您可以使用索引向量并rowSums使用Map.

# create index vectors
id.99 <- grep("_99", names(d))
id.88 <- grep("_88", names(d))

d[id.99] <- Map(function(x, y) rowSums(cbind(x, y), na.rm=TRUE), d[id.88], d[id.99])
d <- d[-id.88]  # drop "88" columns
#   nb C1_1_66 C1_1_77 C1_1_99 C1_2_66 C1_2_77 C1_2_99 C2_1_66 C2_1_77 C2_1_99
# 1 33     160     270     207      NA      NA       2     120     170     350
# 2 54       7      18       5       1      45       0      NA      NA       0
# 3 72      72      25      46      NA      NA      77      90     102       0
于 2020-03-06T14:59:19.337 回答