【问题标题】:Recode observation in column depending on different column根据不同的列重新编码列中的观察
【发布时间】:2020-12-20 21:21:50
【问题描述】:

我有一个名为“调查”的数据集,其中包含个人 ID 行和包含许多问题的列。我需要将 1 列中的值重新编码为 NA 并将观察结果移动到另一列。

例如:

ID    Food    Vegetable 
aaa   NA       NA 
bbb   NA       lemon
ccc   NA       sprout
ddd   fruit    NA
eee   fruit    NA
fff   NA       watermelon

我想将属于 ID bbbffflemonwatermelon 观察值更改为将它们放入 Food 列并将它们重命名为 fruit(调查受访者将它们放在错误的位置列)并将NA 留在vegetable 列中。

看起来像:

   ID    Food        Vegetable 
    aaa   NA         NA 
    bbb   fruit      NA
    ccc   NA         sprout
    ddd   fruit      NA
    eee   fruit      NA
    fff   fruit      NA       

我用过:

survey<- survey %>%
    mutate(food = if_else(str_detect(Vegetable,"(lemon)|(watermelon)"),"fruit", Food))
 

这可以将food 列中的NA 转换为fruit,但它不能与vegetable 列中的NA 一致,它还会转换food 中的所有其他水果列到NA

数据:

    structure(list(ID = c("aaa", "bbb", "ccc", "ddd", "eee", "fff"
), Food = c(NA, NA, NA, "fruit", "fruit", NA), Vegetable = c(NA, 
"lemon", "sprout", NA, NA, "watermelon")), class = "data.frame", row.names = c(NA, 
-6L))

P.S.:这是对a previous question I asked 的跟进,已得到答复。这与以前的问题不完全相同,这就是我开始一个新问题的原因。

dplyr 版本 (1.0.2)

【问题讨论】:

  • 这一步之后可以做mutate(Vegetable = NA_character_)

标签: r data-cleaning recode


【解决方案1】:

一种选择是根据Vegetable 值是否为%in% 给定列表not_vegetables 来更新FoodVegetable

not_vegetables <- c("grape", "tomato")

df %>%
  mutate(Food = if_else(Vegetable %in% not_vegetables, "fruit", Food),
         Vegetable = if_else(Vegetable %in% not_vegetables, NA_character_, Vegetable))

另一种方法是replaceacross 两列,并在里面做if_else

df %>%
  mutate(across(
    c(Food, Vegetable), 
    ~replace(., 
             Vegetable %in% not_vegetables, 
             if_else(cur_column() == "Food", 'fruit', NA_character_))
    ))

【讨论】:

  • 不幸的是,这些似乎都不起作用?第一个解决方案运行,但没有更改数据。第二种解决方案报错:Error: Problem with `mutate()` input `..1`. x Formula shorthand must be wrapped in `where()`. # Bad data %&gt;% select(~...) # Good data %&gt;% select(where(~...)) ℹ Input `..1` is `across(...)`. Backtrace: &gt;
  • 我在发布之前都在本地进行了测试,听起来像是版本问题,和/或您的真实数据是如何设置的。你有什么版本的 dplyr? across 于四月推出。您可以编辑您的帖子以包含您的数据或您的玩具df 的dput 吗?这样可以更轻松地了解正在发生的事情。
  • 奇怪的是,当我在新的 R 文件中执行此操作时,它可以工作...%in% 是否可能被另一个包屏蔽?
  • 很高兴它成功了。重新屏蔽,也许?您可以查看conflicts(detail=TRUE) 以了解您的环境中哪些函数存在冲突。请注意,%in% 是一个基本的 R 函数,我认为 tidyverse 中的任何内容都不会覆盖它。
【解决方案2】:

使用 base R 你可以试试这个:

#Conditional
values <- c('grape','tomato')
df$Food <- ifelse(df$Vegetable %in% values,'fruit',df$Food)
df$Vegetable <- ifelse(df$Vegetable %in% values,NA,df$Vegetable)

输出:

df
   ID  Food Vegetable
1 aaa fruit      <NA>
2 bbb fruit      <NA>
3 ccc fruit      <NA>
4 ddd fruit      <NA>

数据

df <- structure(list(ID = c("aaa", "bbb", "ccc", "ddd"), Food = c(NA, 
NA, "fruit", "fruit"), Vegetable = c("grape", "tomato", NA, NA
)), class = "data.frame", row.names = c(NA, -4L))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 2021-04-21
    • 1970-01-01
    • 2023-01-18
    相关资源
    最近更新 更多