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)
我在更改 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)