gsub() 在具有多个替换的数据框中的所有值上

gsub() on all values in a dataframe with multiple replacements

我有一个大型数据框,其中包含指示数千个位置 (Land_Use) 随时间推移(从 1972 年到 2020 年每年)的土地使用情况的字符串。有 23 个土地使用字符串(在我的数据框中定义为因素),我想将它们简化为 3 个。我在另一个数据框(简单)中匹配了这些简化,我目前没有在代码中使用它,但我觉得就像我可以通过某种方式使它更有效率。

例如,我想用一个名为“water”的字符串替换所有土地使用字符串“lake”、“ocean”、“river”、“pond”。所有的土地都使用字符串来表示“原生森林”、“异国森林”……以及一个名为“森林”的字符串。所有土地都使用字符串表示“养猪业”、“异国草原”、“日记业”,...用一个字符串称为“牧场”

我已经使用 gsub 和 lapply 进行了各种尝试,但我无法让它工作。

我该怎么做,是否有一种有效的方法可以同时对整个数据框执行此操作,或者我是否需要逐列进行,土地使用逐个进行?

Land_Use <- read.csv("Data\Land_Use.csv")
Simple <- read.csv("Data\Land_Use_simplified_classes.csv")

Land_Use <- gsub('native forest','forest.',Land_Use72)  # the replacement works but my dataframe become a vector containing only data from 1972

lapply(Land_Use, function(y) gsub("native forest", "forest", y))  # something very weird happened - I think it has converted to a list, not sure if the replacement worked

lapply returns 一个列表,您可以使用 [] 将其分配给数据框以保持尺寸。

Land_Use[] <- lapply(Land_Use, function(y) gsub("native forest", "forest", y))

此处 gsub 将应用于数据框中的所有列。

对于一列,您需要再次将输出分配回列而不是数据框。

Land_Use$`1972` <- gsub('native forest','forest.',Land_Use$`1972`)

如果您想将多个值更改为一个值,您可能需要查看 forcats.

中的 fct_collapse 函数
library(dplyr)
library(forcats)

Land_Use %>%
  mutate(across(.fns = ~fct_collapse(.x, 'Forest' = c('native forest', 'exotic forest'), 
                             'water' = c('lake', 'river', 'ocean', 'pond')))) -> Land_Use

Land_Use

我相信有更好的方法,但这很有效而且很简单。对于每组替换,您可以 运行 一个单独的 sub 操作(不需要 gsub,因为每个值只有一个匹配项)。对于每个替换集,您可以使用交替模式,对于被 water 替换的项目,或者使用字符串中的规律性,例如要替换为 forest 的集合中的重复 forest,以及要用 pasture 替换的值集中 grasslandfarming 的重复:

df[] <- lapply(df, function(x) sub("\b(lake|ocean|river|pond)\b", "water", x))
df[] <- lapply(df, function(x) sub(".*(forest)", "\1", x)) # also: sub(".*(forest)", "forest", x)
df[] <- lapply(df, function(x) sub(".*(farming|grassland)", "pasture", x))

结果:

df
        x      y       z
1   water forest pasture
2   water forest pasture
3   water forest pasture
4   water forest pasture
5  forest  water  forest
6  forest  water   water
7 pasture  water   water

数据:

df <- data.frame(
  x = c("lake", "ocean", "river", "pond","native forest", "exotic forest", "diary farming"),
  y = c("native forest", "exotic forest", "native forest", "exotic forest","lake", "ocean", "river"),
  z = c("pig farming", "exotic grassland", "diary farming", "exotic grassland","exotic forest","lake", "ocean")
)