R 将非连续索引更改为连续索引

R 将非连续索引更改为连续索引,r,R,我有这样的数据: doc_id sentence_id token_id head_token_id 1 doc1 1 1 0 2 doc1 1 2 1 3 doc1 1 3 1 4 doc1 1 4 3 5 doc1

我有这样的数据:

   doc_id sentence_id token_id head_token_id
1    doc1           1        1             0
2    doc1           1        2             1
3    doc1           1        3             1
4    doc1           1        4             3
5    doc1           1        5             4
6    doc1           1        6             1
7    doc1           2        1             2
8    doc1           2        2             0
9    doc1           2        3             2
10   doc1           2        4             3
11   doc1           2        5             2
12   doc2           1        1             0
13   doc2           1        2             1
14   doc2           1        3             4
15   doc2           1        4             1
数据按“文档id”和“句子id”列分组。“head\u token\u id”列是订单列。但是,顺序值不是连续的。例如,
doc\u id==“doc\u 1”
句子\u id==1
的“head\u-token\u-id”的值是
0、1、1、3、4、1
。我想将它们更改为连续值
0、1、1、2、3、1
。我想在每组“文档id”和“句子id”中都这样做

我想要的输出是这样的,带有新的\u head\u token\u id列。 head_token_id中的数字0和1始终相同。但其余的数字可能相同,也可能不同。In取决于这个句子中是否有前面的数字。比如说

   doc_id sentence_id token_id head_token_id new_head_token_id
4    doc1           1        4             3                 2
这里我们看到head_token_id中的3变为2,因为head_token_id列中的这个句子(第1句,doc 1)中没有数字2。我尝试删除“数字跳跃”

   doc_id sentence_id token_id head_token_id new_head_token_id
1    doc1           1        1             0                 0
2    doc1           1        2             1                 1
3    doc1           1        3             1                 1
4    doc1           1        4             3                 2
5    doc1           1        5             4                 3
6    doc1           1        6             1                 1
7    doc1           2        1             2                 1
8    doc1           2        2             0                 0
9    doc1           2        3             2                 1
10   doc1           2        4             3                 2
11   doc1           2        5             2                 1
12   doc2           1        1             0                 0
13   doc2           1        2             1                 1
14   doc2           1        3             4                 2
15   doc2           1        4             1                 1
我认为代码的第一部分应该是这样的

for (i in unique(df$doc_id)){
  for(j in unique(df$sentence_id){
    for(k in df$token_id){
      if(df$head_token_id[k] == 0){df$new_head_token_id[k] = 0} else
        if(df$head_token_id[k] == 1){df$new_head_token_id[k] = 1}
    }
  }
}

将变量视为一个因素,重新标记非常容易。然后我们可以强制它返回数值。我们使用的事实是,
unique()
将按照唯一值出现的顺序提供唯一值的向量

我们想要对向量
x
执行的操作是

as.numeric(as.character(
  factor(x, levels = unique(x), labels = seq_along(unique(x)) - 1)
))
这将按照出现的顺序重新标记
x
的唯一值。
-1
使其从0开始,而不是从1开始。我们强迫回到数字。我们将把它变成一个函数:

label0 = function(x) {
    as.numeric(as.character(
      factor(x, levels = unique(x), labels = seq_along(unique(x)) - 1)
    ))
}
最后,选择您最喜欢的通过分组变量应用函数的方法。我将使用
dplyr
,但您可以使用
data.table
base::ave
base::by
split;重叠;rbind
等。这些方法的示例以及更多内容可以在R-FAQ上找到,您只需要使用
label0
而不是
sum

library(dplyr)
group_by(dat, doc_id, sentence_id) %>% mutate(new_head_token_id = label0(head_token_id))
# # A tibble: 15 x 5
# # Groups:   doc_id, sentence_id [3]
#    doc_id sentence_id token_id head_token_id new_head_token_id
#    <fctr>       <int>    <int>         <int>             <dbl>
#  1   doc1           1        1             0                 0
#  2   doc1           1        2             1                 1
#  3   doc1           1        3             1                 1
#  4   doc1           1        4             3                 2
#  5   doc1           1        5             4                 3
#  6   doc1           1        6             1                 1
#  7   doc1           2        1             2                 0
#  8   doc1           2        2             0                 1
#  9   doc1           2        3             2                 0
# 10   doc1           2        4             3                 2
# 11   doc1           2        5             2                 0
# 12   doc2           1        1             0                 0
# 13   doc2           1        2             1                 1
# 14   doc2           1        3             4                 2
# 15   doc2           1        4             1                 1

我有答案。在一个文档和一句话中,我们必须找出有多少唯一值低于当前检查值,并替换此数字上的当前值。 例如,doc_id==“doc_1”和句子_id==1的
“head_token_id”的值为0、1、1、3、4、1。
对于值3,只有两个唯一的值较低(0和1)。所以我们想把3改成2

代码如下:

levels<-function(parsedDataFrame)
{parsedDataFrame$head_token_id=as.numeric(parsedDataFrame$head_token_id)
for(doc in unique(parsedDataFrame[,1]))
    {for(prg in unique(parsedDataFrame[,2]))
        {for(stc in unique(parsedDataFrame[,3]))
            {
                newDataFrame=parsedDataFrame[which(parsedDataFrame[,1]==doc & parsedDataFrame[,2]==prg & parsedDataFrame[,3]==stc),]
                newDataFrame$sentenceLevel=sapply(newDataFrame$head_token_id,function(y) length(which(y>unique(newDataFrame$head_token_id))))

                if(exists("levelsDF"))
                  levelsDF=rbind(levelsDF,newDataFrame)
                else levelsDF=newDataFrame
            }
        }   
    }
    return(levelsDF)    
}
levelsunique(新数据帧$head\u令牌\u id)))
如果(存在(“levelsDF”))
levelsDF=rbind(levelsDF,newDataFrame)
else levelsDF=newDataFrame
}
}   
}
返回(levelsDF)
}

此操作的算法是什么?如果你只是想改变顺序,给DF传递一个行号向量来反映这一点。我试图找出这个算法,因为实际上我有一个非常大的数据集,包含100000个文档,我不明白的是,
head\u token\u id
中的第七个数字是2?是的,head\u token\u id中的第七个数字是2。第七个数字是doc1第二句中的第一个单词。doc1,sentence2和doc2,sentence1在新的\u head\u token\u id列中是错误的。当我在我的计算机上使用您的代码时,只有doc1,sentence2是错误的。抱歉,没有意识到您还需要按句子分组。只需将其添加到groupby:
groupby(dat,doc\u id,句子id)
,其余的都一样。答案编辑好了,还是不行。看doc1的句子2。。0和1应始终保持不变
levels<-function(parsedDataFrame)
{parsedDataFrame$head_token_id=as.numeric(parsedDataFrame$head_token_id)
for(doc in unique(parsedDataFrame[,1]))
    {for(prg in unique(parsedDataFrame[,2]))
        {for(stc in unique(parsedDataFrame[,3]))
            {
                newDataFrame=parsedDataFrame[which(parsedDataFrame[,1]==doc & parsedDataFrame[,2]==prg & parsedDataFrame[,3]==stc),]
                newDataFrame$sentenceLevel=sapply(newDataFrame$head_token_id,function(y) length(which(y>unique(newDataFrame$head_token_id))))

                if(exists("levelsDF"))
                  levelsDF=rbind(levelsDF,newDataFrame)
                else levelsDF=newDataFrame
            }
        }   
    }
    return(levelsDF)    
}