R:根据其他列的值更改某些列的值,但不是全部更改:ifelse()和if(){}的问题

时间:2019-04-01 05:38:54

标签: r if-statement

如果某个值出现在另一列(A)中,则我想更改某一列(B)中的某些值,否则要使这些列值保持不变。例如,在以下简化的数据版本中,如果A列的值为“ none”,我想将B列的值更改为“ 0”,否则我希望B列的值保持不变

df <- data.frame(ID=c(1:4),A=c("1/wk","none","1/mo","1/wk"),B=c("3",NA,NA,"depends"))
    > df
      ID    A       B
    1  1 1/wk       3
    2  2 none    <NA>
    3  3 1/mo    <NA>
    4  4 1/wk depends

我尝试过

df$B <- ifelse(df$A == "none","0",df$B)
    > df
      ID    A    B
    1  1 1/wk    1
    2  2 none    0
    3  3 1/mo <NA>
    4  4 1/wk    2

虽然这确实将B列中的ID 2更改为“ 0”(我想要),但它也更改了B列中的其他值。我希望我的输出看起来像这样:

> df
  ID    A       B
1  1 1/wk       3
2  2 none       0
3  3 1/mo    <NA>
4  4 1/wk depends

我也尝试使用if(){},但在涉及多个列时却不知道如何使用它

我并不确定要使用什么功能(尽管我更喜欢使用基数R的答案)。 PS-虽然我在stackoverflow上发现了类似的问题,但没有一个答案对我有用。

2 个答案:

答案 0 :(得分:3)

尝试在不使用因素的情况下创建数据框:

df <- data.frame(ID=c(1:4),
                 A=c("1/wk","none","1/mo","1/wk"),
                 B=c("3",NA,NA,"depends"),
                 stringsAsFactors=FALSE)      # add this
df$B <- ifelse(df$A == "none","0",df$B)
df

  ID    A       B
1  1 1/wk       3
2  2 none       0
3  3 1/mo    <NA>
4  4 1/wk depends

比较的问题是您是针对 factor 级别进行的,而不是它们代表的值。

以下是您当前进行的比较:

df$A [
    "1/wk" != "none"  => "1" (first factor level of df$B)
    "none" == "none"  => "0" (the comparison having been true)
    "1/mo" != "none"  => NA  (comparison failed, NA still NA for factors)
    "1/wk" != "none"  => "2" (second factor level of df$B)
]

答案 1 :(得分:0)

问题在于,默认情况下,您的列不是字符向量而是因素。

尝试一下:

df <- data.frame(ID=c(1:4),A=c("1/wk","none","1/mo","1/wk"),B=c("3",NA,NA,"depends"), stringsAsFactors = FALSE)