R如何改变行的子集

R How to mutate a subset of rows

我在更改 dplyr 中的一部分行时遇到问题。我正在使用链接命令:%>% 表示:

data <- data %>%
  filter(ColA == "ABC") %>%
  mutate(ColB = "XXXX")

这工作正常,但问题是我希望能够 select 整个原始 table 并看到仅应用于我指定的数据子集的变异。我的问题是,当我在此之后查看数据时,我只能看到 data 的子集及其更新的 ColB 信息。

我也想知道如何使用 data.table

谢谢。

当您使用 filter() 时,您实际上是在删除与您指定的条件不匹配的行,因此它们不会出现在最终数据集中。

ColB 是否已存在于您的数据框中?如果是这样,

data %>%
  mutate(ColB = ifelse(ColA == "ABC", "XXXX", ColB))

将在 ColA == "ABC" 时将 ColB 更改为 "XXXX",否则保持原样。如果 ColB 尚不存在,则您必须指定对 ColA != "ABC" 所在的行执行的操作,例如:

data %>%
  mutate(ColB = ifelse(ColA == "ABC", "XXXX", NA))

另一种选择是对相同的数据进行联合和反联合的后续组合。这需要一个主键:

data <- data %>%
  filter(ColA == "ABC") %>%
  mutate(ColB = "XXXX") %>%
  rbind_list(., anti_join(data, ., by = ...))

示例:

mtcars_n <- mtcars %>% add_rownames
mtcars_n %>%
  filter(cyl > 6) %>%
  mutate(mpg = 1) %>%
  rbind_list(., anti_join(mtcars_n, ., by = "rowname"))

这可能比任何其他方法都慢得多,但对于通过扩展现有管道快速获得结果很有用。

使用 data.table,我们会做:

setDT(data)[colA == "ABC", ColB := "XXXX"]

并且值被修改 就地 ,与 if-else 不同,后者会复制整个列以仅替换满足条件的那些行。

我们通过引用称其为子分配。您可以在 new HTML vignettes.

中阅读更多相关信息

刚刚更新 (到 2022 年 6 月 2 日) @krlmlr 很好的回答:

add_rownames() 已弃用,请改用 tibble::rownames_to_column()rbind_list 也已弃用,请使用 bind_rows 代替

您可能还会在生成的连接数据集中发现不同的行序列,这取决于您的目标,之后很难用 dplyr::arrange() 进行更正。

一个替代方案,虽然速度较慢,但​​是:

mtcars_n <- mtcars %>% 
  add_rownames() %>% 
  filter(cyl > 6) %>%
  mutate(new_col = 1)
mtcars_m <- left_join(x=mtcars, y=mtcars_n)