当字符串值与上一行相同时,将“ NA”输出到新列中

时间:2018-12-23 17:22:11

标签: r

使用R,我正在尝试向数据集添加一个新列,该数据集将该列复制到左侧,当字符串与上面的行相同时,将字符串值替换为“ NA”。

最好用一些数据来解释。我的数据集当前如下所示:

   x.id x.timestamp x.action
71    1  1435114605   click
72    1  1435114606   click
73    1  1435114659   click
74    1  1435114719  scroll
75    1  1435114726  scroll
76    1  1435114780  scroll
77    1  1435155998  scroll
78    1  1435156059  scroll
79    1  1435156076   click
80    1  1435156119   click

我想得到的输出是这样:

   x.id x.timestamp x.action x.mutate
71    1  1435114605   click   click
72    1  1435114606   click      NA
73    1  1435114659   click      NA
74    1  1435114719  scroll  scroll
75    1  1435114726  scroll      NA
76    1  1435114780  scroll      NA
77    1  1435155998  scroll      NA
78    1  1435156059  scroll      NA
79    1  1435156076  scroll   click
80    1  1435156119  scroll      NA

如您所见,右侧列将重复项替换为“ NA”。但是,随着以后重复相同的值,我不能只使用重复的或唯一的函数。

以前的尝试

  1. 这与这个问题非常相似,我尝试了一些方法,但是由于这些是字符而不是数字,因此给了我一个错误:Delete the entire row if the a value in value is equal to previous row in R

  2. 然后,我尝试在下面显示for循环,但收到此错误: “时间戳[[i]]中的错误:'closure'类型的对象不可子集化”

    for(i in 1:length(timestamp))
     {
    if (timestamp[[i]] == min(timestamp)) event_type[[i]] <- event_type[[i]]
    else if(event_type[[i + 1]] == event_type[[i]]) event_type[[i + 1]] <- "NA"
    else if(event_type[[i + 1]] != event_type[[i]]) event_type[[i + 1]] <- event_type[[i + 1]]
     }
    

关于如何在上面显示的第二个数据集上创建额外的“ x.mutate”列的任何想法?我有点迷茫,任何帮助不胜感激:-)

3 个答案:

答案 0 :(得分:3)

1)rleid / ave 使用末尾注释中可重复显示的数据,并使用data.table包中的rleid,我们定义一个函数x1_na它将向量参数的所有元素替换为NA,但第一个除外,然后将其应用ave

library(data.table)

x1_na <- function(x) `length<-`(x[1], length(x))
transform(DF, x.mutate = ave(x.action, rleid(x.action), FUN = x1_na))

给予:

   x.id x.timestamp x.action x.mutate
71    1  1435114605    click    click
72    1  1435114606    click     <NA>
73    1  1435114659    click     <NA>
74    1  1435114719   scroll   scroll
75    1  1435114726   scroll     <NA>
76    1  1435114780   scroll     <NA>
77    1  1435155998   scroll     <NA>
78    1  1435156059   scroll     <NA>
79    1  1435156076    click    click
80    1  1435156119    click     <NA>

2)随机/重复上述内容的一种变化是:

transform(DF, x.mutate = replace(x.action, duplicated(rleid(x.action)), NA))

3)基本R 上面的唯一非基本部分是rleid,因此,如果您需要基本R解决方案,请使用上述方法之一,但自己定义rleid像这样:

rleid <- function(x) with(rle(x), rep(seq_along(lengths), lengths))

注意

我们假设输入内容以可重复的形式显示如下。特别要注意的是,最后一列是字符(如问题的“先前尝试”部分中的问题所述)。

Lines <- "
   x.id x.timestamp x.action
71    1  1435114605   click
72    1  1435114606   click
73    1  1435114659   click
74    1  1435114719  scroll
75    1  1435114726  scroll
76    1  1435114780  scroll
77    1  1435155998  scroll
78    1  1435156059  scroll
79    1  1435156076   click
80    1  1435156119   click"
DF <- read.table(text = Lines, as.is = TRUE)

答案 1 :(得分:2)

使用dplyr,您可以执行以下操作:

df %>%
 mutate(res = ifelse(x.action == lag(x.action) & row_number() != min(row_number()), NA, x.action))

   x.id x.timestamp x.action    res
1     1  1435114605    click  click
2     1  1435114606    click   <NA>
3     1  1435114659    click   <NA>
4     1  1435114719   scroll scroll
5     1  1435114726   scroll   <NA>
6     1  1435114780   scroll   <NA>
7     1  1435155998   scroll   <NA>
8     1  1435156059   scroll   <NA>
9     1  1435156076    click  click
10    1  1435156119    click   <NA>

或以一种简化的方式(由@Konrad Rudolph提出):

df %>%
 mutate(res = ifelse(x.action == lag(x.action, default = ""), NA, x.action))

它只是比较“ x.action”是否具有与先前的“ x.action”相同的值。对于第一行,它只是从“ x.action”分配其值。

答案 2 :(得分:1)

如果您将FALSE(因为第一项永远不是连续重复项)作为第一项附加到headtail的相等向量中,则可以在{{ 1}}。 is.na<-函数使用赋值运算符RHS上的逻辑向量来指定括号中向量中哪些项重新分配给NA:

is.na<-