replace()中的奇怪行为

时间:2018-10-22 11:53:41

标签: r

我有一组环境数据(env_PLI),其中一个变量是season_year。该变量的两个值是“ Autumn 2016”和“ Summer 2017”。为了进行分析,我需要将变量从字符更改为数字,因此我尝试将其更改为将级别更改为2016和2017。但是,代码

env_PLI$season_year <- replace(env_PLI$season_year,
                       c("autumn 2016", "summer 2017"), c(2016, 2017))

给我错误

Error in `$<-.data.frame`(`*tmp*`, season_year, value = c("autumn 2016",  : 
  replacement has 52 rows, data has 50

我尝试使用谷歌搜索,但结果却无济于事,因为他们似乎大多说要在使用replace()之前创建变量,但就我而言,我是在现有变量上使用它的。我在这里还有什么错呢?

4 个答案:

答案 0 :(得分:2)

给出一个引导season_year <- c("A", "autumn 2016", "summer 2017")呼叫

replace(season_year, c("autumn 2016", "summer 2017"), c(2016, 2017))

结果

#                                   autumn 2016   summer 2017 
# "A" "autumn 2016" "summer 2017"        "2016"        "2017" 

当您查看replace的情况

function (x, list, values) 
{
    x[list] <- values
    x
}

您可能会发现自己的错误:将两个条目附加到引导程序上。这就是为什么错误“替换有52行,数据有50行”(在数据框中,每一列中必须有同样多的条目)的原因。

改为尝试%in%

replace(season_year, season_year %in% c("autumn 2016", "summer 2017"), c(2016, 2017))
#[1] "A"    "2016" "2017"

注释

此方法适用于上面的虚拟矢量。如果in无法处理您的数据,请执行以下操作:1)考虑给出一个可重现的示例,以及2)尝试

env_PLI$season_year[env_PLI$season_year == "autumn 2016"] <- "2016"
env_PLI$season_year[env_PLI$season_year == "autumn 2017"] <- "2017"

或尝试

env_PLI$season_year <- gsub("(autumn|summer)\\s+", "", env_PLI$season_year)
# similar to @Moody_Mudskipper's second solution

感谢@RichardTelford和@Duckmayr。

答案 1 :(得分:1)

您可以考虑以下几种不同的选择:

readr::parse_number(c("autumn 2016", "summer 2017"))
# [1] 2016 2017
gsub("\\D","",c("autumn 2016", "summer 2017")) # could be wrapped into as.numeric
# [1] "2016" "2017"

答案 2 :(得分:1)

马库斯(Marcus)解释了为什么replace有问题,但是他给出的解决方案在某些情况下会失败。

有多种解决方案来改变向量中的值。

season_year <- c("A", "autumn 2016", "summer 2017", "summer 2017") 

plyr::mapvalues是您原始代码的直接替代。当我在data.frame中有from和to向量时,例如字典,我发现这最有用。

plyr::mapvalues(season_year, from = c("autumn 2016", "summer 2017"), to = c(2016, 2017))
[1] "A"    "2016" "2017" "2017"

dplyr::recode采用旧值和新值对。

dplyr::recode(season_year, "autumn 2016" = "2016", "summer 2017" = "2017")
[1] "A"    "2016" "2017" "2017"

您可以使用正则表达式提取年份。 \\d{4}寻找一个四位数的序列。当数据需要清理时,正则表达式非常强大。

gsub(pattern = ".*(\\d{4})", replacement = "\\1", season_year)
[1] "A"    "2016" "2017" "2017"

答案 3 :(得分:0)

如果我误解了你的问题,请原谅我。

library(tidyverse)
dummydf<-data.frame(Id=c(1,2),Period=c("autumn 2006","spring 2007"))
#Change to character
dummydf %>% 
  mutate(Period=as.character(Period))
#Back to numeric
dummydf %>% 
  mutate(Period=as.numeric(Period))

也许是这个

dummydf$Period %>% 
str_replace_all("autumn","")