【问题标题】:Change some numerical values in data frame更改数据框中的一些数值
【发布时间】:2019-05-13 16:39:30
【问题描述】:

我有一个数据框,其中两个变量(纬度和经度)的值不正确。数据框中的错误值列为 999.00,正确的值应分别为 42.68 和 -72.47。

我想要一种简单的方法来使用 dplyr 替换这些值,但我的尝试(见下文)没有成功(下面提供了错误)。

df$Lat2 <- recode(df$Lat, "999.00"="42.68", .default=x)

lapply(x, f) 中的错误:找不到对象“x”

df <- df %>%
mutate(Lat2 = if_else(Lat == 999.00, 42.68, NULL, NULL))

mutate_impl(.data, dots) 中的错误: 评估错误:未使用的参数 (recvLat = 999)。

df <- df %>%
mutate(Lat2 = ifelse(Lat == 999.00, 42.68, NULL))

mutate_impl(.data, dots) 中的错误: 评估错误:替换的长度为零。 另外:警告信息: 在 rep(no, length.out = length(ans)) : 'x' 为 NULL,因此结果将为 NULL

df <- df %>%
mutate(Lat2 = case_when(Lat == 999.00 ~ 42.68, TRUE ~ NULL))

mutate_impl(.data, dots) 中的错误: 评估错误:下标超出范围。

对于后三个尝试,如果数字在引号中(即“999.00”和“42.68”),我会得到相同的错误

【问题讨论】:

  • 您的ifelse 语句应该以实际列作为替代,而不是NULL,即ifelse(..,..., df$Lat)
  • 这不能用df$Lat &lt;- df$Lat %&gt;% gsub("999.00", "42.68")解决吗?
  • @huan... 不。df$Lat 是数值变量,不是字符串
  • 类似:as_tibble(df) %>% mutate(Lon = case_when(revcLat == 999 ~ 42.68), Lat2 = case_when(Lat == 999 ~ -72.47))

标签: r dplyr tidyr


【解决方案1】:

我们可以将NULL 放在list

df %>%
    mutate(Lat2 = ifelse(recvLat == 999.00, 42.68, list(NULL)))
#  recvLat  Lat2
#1   999.0 42.68
#2     1.5  NULL
#3     2.5  NULL

可以是NA,而不是NULL

df %>%
    mutate(Lat2 = ifelse(recvLat == 999.00, 42.68, NA_real_))
#  recvLat  Lat2
#1   999.0 42.68
#2     1.5    NA
#3     2.5    NA

如果我们想反其道而行之,只需使用!=

df %>%
    mutate(Lat2 = ifelse(recvLat != 999.00, 42.68, NA_real_))

根据 OP 的评论,

df %>%
    mutate(Lat2 = ifelse(recvLat == 999.00, 42.68, recvLat))

base R,我们可以通过创建索引来做到这一点

i1 <- df$recvLat == 999
df$recLat[i1] <- 42.68

注意:两种解决方案都有效。

数据

df <- data.frame(recvLat = c(999, 1.5,  2.5))

【讨论】:

  • 我不再收到错误消息,但我想保留所有不是 999 的原始值,而不是把它们变成 NULLs
  • @user3220999 请检查您的代码mutate(Lat2 = ifelse(recvLat == 999.00, 42.68, NULL)) 这与我在这里使用的代码相同。在这里,条件是 999 的值更改为 42.68,其他值更改为 NULL
  • @user3220999 我现在不明白这个问题。您已经展示了将值分配给NULL 的代码,现在不需要了??
  • 啊,我出错了,第一个ifelse语句应该是if_else。我希望所有 999 都是 42.68,并保留所有其他值,而不是将它们变成 NULL
【解决方案2】:

其实,这也是一个很好的展示data.table优雅的案例。

library(data.table)

## Create example
data <- data.table(lat = c(999, 0, 0),
                   lon = c(0, 999, 0))

## Reassign values
data[lat==999, lat := 42.68]
data[lon==999, lon := -72.47]

## Print results
data
#      lat    lon
# 1: 42.68   0.00
# 2:  0.00 -72.47
# 3:  0.00   0.00

缺点是您必须记住分配需要:=

好处是

  • 您可以按名称引用变量,不带引号
  • 内存高效,对于大型数据集尤其重要
  • 没有依赖关系
  • data.table 语法更加简单且一致(i、j、分组依据)
  • 您无需记住一堆名称怪异的函数,这些函数可能和/或可能不是澳大利亚风格的拼写(如 color 或 summarise)
  • 您可以更多地使用 base R,这使您的代码更具可移植性和更广泛的理解
  • data.table 类继承了data.frame 类,因此在 R 内部更兼容

【讨论】:

  • 感谢@geneorama,但我希望坚持使用 dplyr 功能。
  • @user3220999 没问题! dplyr 绝对是一个很好的起点,尤其是对于更多实验性 R 的使用。
【解决方案3】:

为什么不使用这个。

data=as.data.frame(matrix(0,3,3))
names(data)=c("a","b","c")
data$a[1]=999
data$c[2]=999
data$a[which(data$a==999)]=42.68
data$c[which(data$c==999)]=-72.47
data
      a b      c
1 42.68 0   0.00
2  0.00 0 -72.47
3  0.00 0   0.00

【讨论】:

  • 前四行只是重新创建数据。您只需要最后两个来更正您的数据。
  • 有没有办法在 dplyr 中做到这一点?我需要将变量保存在数据框中以进行进一步分析。
  • 我不太明白。这样,所有变量都保存在您的数据框中,唯一的区别是 Lat 和 Lon 列中的更新值。您甚至可以保存已更正的点的索引
  • 啊。我误解了你在我最初通读时所做的事情。虽然我更喜欢在 dplyr 中工作,但我可以看到这也非常简单有效。
猜你喜欢
  • 1970-01-01
  • 2022-12-06
  • 2019-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-16
相关资源
最近更新 更多