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
替换的值集中 grassland
或 farming
的重复:
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")
)
我有一个大型数据框,其中包含指示数千个位置 (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
替换的值集中 grassland
或 farming
的重复:
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")
)