当需要计算r中的每个子集时,避免for循环

当需要计算r中的每个子集时,避免for循环,r,subset,R,Subset,dput(列表[200:250]) 我的代码: for (i in 1:(max(list$id))) { p <- subset(list,list$id==i) h <-0 for (j in 1:(nrow(p)-1)){ if (p$group[j]!=p$group[(j+1)]) { h <- (h+1) } } list$group_move[list$id==i] <- h } 我检查了N/A

dput(列表[200:250])

我的代码:

for (i in 1:(max(list$id))) {
  p <- subset(list,list$id==i)
  h <-0
  for (j in 1:(nrow(p)-1)){ 
    if (p$group[j]!=p$group[(j+1)]) {
      h <- (h+1)
      } 
    }
  list$group_move[list$id==i] <- h
}
  • 我检查了N/A(is.na(list)),结果是错误的
关于我的名单:

我有5000个身份证,我可以用“34526”作为身份证。 我需要计算每个不同id在第1、2和3组之间移动的次数。 我知道2“for”不是很有效,但我不知道如何区分每个id

如果你能帮助我理解我的代码有什么问题,那就太好了。
如果您知道一种为每个不同的id编写推荐的方法,那就更好了(推荐不是常规函数)。

使用
dplyr
并调用数据
dd

library(dplyr)
dd %>% 
    group_by(id) %>% 
    summarize(changes = sum(lag(group) != group, na.rm = T))
# # A tibble: 3 × 2
#      id changes
#   <int>   <int>
# 1    10       0
# 2    12       7
# 3    14       8
我认为您的代码唯一的问题是它可能会命中不存在的
id
值。这将导致空子集和丢失条件错误。一个简单的修复方法是将(i in 1:(max(list$id)))替换为(i in unique(list$id)):


这基本上就是我们在顶部使用的
dplyr
所做的-
lag()
是一个方便的函数来抵消索引,而
groupby()
分别处理每个
id

示例数据在
组之间没有移动。请提供一个最小的可重复的例子。@MichaelChirico在Q中更改它。如果我想计算每个id的标准偏差和斜率,我该怎么做?这样行吗?h%groupby(id)%%>%summary(new_list=sd(value),na.rm=T)几乎,您希望
na.rm=T
成为
sd()
的参数,而不是
summary()
。那么我需要更改什么呢?您有
summary(new_list=sd(value),na.rm=T)
-查看
na.rm=T
如何超出
sd
的结束部分?将其更改为放入
sd()
中。因此,您应该有
摘要(new_list=sd(value,na.rm=T))
。如果您的数据中没有缺失值(那么您根本不需要
na.rm=t
),这并不重要,
na.rm=t
只在我的答案中需要,因为我的
lag(group)
创建了一个缺失值,它将
1,2,3
变成
na,1,2
Error in if (p$group[j] != p$group[(j + 1)]) { : 
  missing value where TRUE/FALSE needed
library(dplyr)
dd %>% 
    group_by(id) %>% 
    summarize(changes = sum(lag(group) != group, na.rm = T))
# # A tibble: 3 × 2
#      id changes
#   <int>   <int>
# 1    10       0
# 2    12       7
# 3    14       8
dd2 = dd %>% 
    group_by(id) %>% 
    mutate(group_move = sum(lag(group) != group, na.rm = T))
dd2
# Source: local data frame [51 x 3]
# Groups: id [3]
# 
#       id group group_move
#    <int> <dbl>      <int>
# 1     10     3          0
# 2     10     3          0
# 3     10     3          0
# 4     10     3          0
# 5     10     3          0
# 6     10     3          0
# 7     12     2          7
# 8     12     2          7
# 9     12     1          7
# 10    12     3          7
# # ... with 41 more rows
list = dd

for (i in unique(list$id)) {
  p <- subset(list,list$id==i)
  h <-0
  for (j in 1:(nrow(p)-1)){ 
    if (p$group[j] != p$group[(j+1)]) {
      h <- (h+1)
    } 
  }
  list$group_move[list$id==i] <- h
}
for (i in unique(list$id)) {
  p <- subset(list,list$id==i)
  h <- sum(p$group[-1] != p$group[-nrow(p)])
  list$group_move[list$id==i] <- h
}