首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将data.table与循环相结合

如何将data.table与循环相结合
EN

Stack Overflow用户
提问于 2016-11-24 09:57:12
回答 3查看 726关注 0票数 2

我的数据看起来是这样的:

代码语言:javascript
运行
复制
> data <- data.frame(A=c(1,1,1,2,2,3,3,3,3,3), B=c("1A","1B","1C","2A","2B","3A","3B","3C","3D","3E"))

我想在变量A和B的函数中添加一个新变量,其结果必须是:

代码语言:javascript
运行
复制
  > data
   A  B LABEL
1  1 1A   1-2
2  1 1B   2-3
3  1 1C   3-4
4  2 2A   1-2
5  2 2B   2-3
6  3 3A   1-2
7  3 3B   2-3
8  3 3C   3-4
9  3 3D   4-5
10 3 3E   5-6

我用data.table函数来尝试这一点。我尝试的代码:

代码语言:javascript
运行
复制
> setDT(data)
> data <- data[,list(LABEL = for(i in 1:length(A)){paste(i, "-", i+1, sep="")}),by=c("A","B")]   

消息错误:“[.data.table__中的错误(data,list(LABEL = for (i in 1:length(A){:第一个组的j的结果的第1列为NULL。我们依赖于第一个结果的列类型来决定其余组的预期类型(并要求一致性)。空列对于以后的组是可以接受的(这些列被适当类型的NA替换并回收),但对于第一个组则不能。请使用键入的空向量,例如整数()或数字()。”

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-11-24 10:00:58

我们可以使用shift在按“A”分组后创建序列的“铅”值,并使用行序列paste来创建“标签”

代码语言:javascript
运行
复制
library(data.table)
setDT(data)[, LABEL := paste(seq_len(.N), shift(seq_len(.N),
                          type='lead', fill= .N+1), sep="-"), by = A]

代码语言:javascript
运行
复制
setDT(data)[, LABEL := paste(seq_len(.N), seq_len(.N)+1, sep = "-"), by = A]
data
#    A  B LABEL
# 1: 1 1A   1-2
# 2: 1 1B   2-3
# 3: 1 1C   3-4
# 4: 2 2A   1-2
# 5: 2 2B   2-3
# 6: 3 3A   1-2
# 7: 3 3B   2-3
# 8: 3 3C   3-4
# 9: 3 3D   4-5
#10: 3 3E   5-6

或者我们可以使用base R方法

代码语言:javascript
运行
复制
i1 <- sequence(tabulate(data$A))
data$LABEL <- paste(i1, i1+1, sep="-")
data$LABEL
#[1] "1-2" "2-3" "3-4" "1-2" "2-3" "1-2" "2-3" "3-4" "4-5" "5-6"
票数 3
EN

Stack Overflow用户

发布于 2016-11-24 10:07:35

您还可以使用dplyr::mutate

代码语言:javascript
运行
复制
library(dplyr)
data %>% 
        group_by(A) %>% 
        mutate(LABEL=paste(seq_along(A),seq_along(A)+1,sep="-"))

在这里,您按A分组,找到沿着组的序列,并连接sequence+1

代码语言:javascript
运行
复制
Source: local data frame [10 x 3]
Groups: A [3]

       A      B LABEL
   <dbl> <fctr> <chr>
1      1     1A   1-2
2      1     1B   2-3
3      1     1C   3-4
4      2     2A   1-2
5      2     2B   2-3
6      3     3A   1-2
7      3     3B   2-3
8      3     3C   3-4
9      3     3D   4-5
10     3     3E   5-6
票数 3
EN

Stack Overflow用户

发布于 2016-11-24 10:20:22

另一个选项是使用base R ave函数。

代码语言:javascript
运行
复制
data$LABEL <- ave(data$A, data$A, FUN = function(x) 
                                      paste0(seq_along(x), "-", seq_along(x)+1))
data
#   A  B LABEL 
#1  1 1A   1-2
#2  1 1B   2-3
#3  1 1C   3-4
#4  2 2A   1-2
#5  2 2B   2-3
#6  3 3A   1-2
#7  3 3B   2-3
#8  3 3C   3-4
#9  3 3D   4-5
#10 3 3E   5-6
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40783124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档