计算某个值出现的次数并将结果添加到列中

Qiy*_*yao 8 r dataframe data.table

我有这个数据框:

   Generacion 1 2 3 4 5 6 NP1 NP2 NP3 NP4 NP5 NP6
1:          1 0 0 0 0 0 0   4   4   4   4   5   5
2:          2 0 0 0 0 0 0   4   4   4   4   4   4
3:          3 0 0 0 0 0 0   5   5   5   5   5   5
4:          4 0 0 0 0 0 0   4   5   5   5   4   4
5:          5 0 0 0 0 0 0   5   4   4   4   4   4
6:          6 0 0 0 0 0 0   5   5   5   5   4   4
Run Code Online (Sandbox Code Playgroud)

我想1通过修改列6,使每列计算该值在右列 ( NP1- NP6) 中的出现次数。也就是说,该4列应该计算出现的次数4。我希望对每个数字重复这个过程。0可以取和之间的值的数字5。最终结果应该是这样的:

head(t2 %>% select(1, 2, 3, 4, 5, 6, 7, NP1, NP2, NP3, NP4, NP5, NP6))
   Generacion 1 2 3 4 5 6 NP1 NP2 NP3 NP4 NP5 NP6
1:          1 0 0 0 4 2 0   4   4   4   4   5   5
2:          2 0 0 0 6 0 0   4   4   4   4   4   4
3:          3 0 0 0 0 6 0   5   5   5   5   5   5
4:          4 0 0 0 3 3 0   4   5   5   5   4   4
5:          5 0 0 0 5 1 0   5   4   4   4   4   4
6:          6 0 0 0 2 4 0   5   5   5   5   4   4
Run Code Online (Sandbox Code Playgroud)

我尝试过使用该包data.table,我做了以下操作:

 t2[NP1 == 4]$`4` <- t2[NP1 == 4]$`4` + 1
Run Code Online (Sandbox Code Playgroud)

但我有以下错误:

[<-.data.table( , NP1 == 4, value = c(1, 1, 1, 1))中的错误*tmp*:无法在同一查询中两次分配给同一列(检测到重复项)。

所以我有两个问题:

  • 为什么我会收到此错误?
  • 有没有更简单、更直观的方法来做到这一点?

Wal*_*ldi 8

data.table

library(data.table)

setDT(t2)

t2[,as.character(1:6):=lapply(1:6, function(n) rowSums(.SD==n)),.SDcols=NP1:NP6][]

#   Generacion 1 2 3 4 5 6 NP1 NP2 NP3 NP4 NP5 NP6
#1:          1 0 0 0 4 2 0   4   4   4   4   5   5
#2:          2 0 0 0 6 0 0   4   4   4   4   4   4
#3:          3 0 0 0 0 6 0   5   5   5   5   5   5
#4:          4 0 0 0 3 3 0   4   5   5   5   4   4
#5:          5 0 0 0 5 1 0   5   4   4   4   4   4
#6:          6 0 0 0 2 4 0   5   5   5   5   4   4
Run Code Online (Sandbox Code Playgroud)

数据:

t2 <- read.table(text=
"Generacion 1 2 3 4 5 6 NP1 NP2 NP3 NP4 NP5 NP6
          1 0 0 0 0 0 0   4   4   4   4   5   5
          2 0 0 0 0 0 0   4   4   4   4   4   4
          3 0 0 0 0 0 0   5   5   5   5   5   5
          4 0 0 0 0 0 0   4   5   5   5   4   4
          5 0 0 0 0 0 0   5   4   4   4   4   4
          6 0 0 0 0 0 0   5   5   5   5   4   4",header=T)

colnames(t2) <- c('Generacion','1','2','3','4','5','6','NP1','NP2','NP3','NP4','NP5','NP6')
Run Code Online (Sandbox Code Playgroud)

  • 使用 t2[,as.character(1:6):=lapply(1:6, function(n) rowSums(.SD==n)), .SDcols 会更加“data.table”规范=模式(“^NP”)]`。(虽然基准测试差异很小,但已证明将“.SD”与“.SDcols”一起使用比“.SD[...]”稍快。) (3认同)

tmf*_*mnk 5

使用的一种选项dplyr可能是(使用更正的列名称导入的数据):

df %>%
    mutate(across(X1:X6, ~ rowSums(across(NP1:NP6) == as.numeric(sub("\\D+", "", cur_column())))))

   Generacion X1 X2 X3 X4 X5 X6 NP1 NP2 NP3 NP4 NP5 NP6
1:          1  0  0  0  4  2  0   4   4   4   4   5   5
2:          2  0  0  0  6  0  0   4   4   4   4   4   4
3:          3  0  0  0  0  6  0   5   5   5   5   5   5
4:          4  0  0  0  3  3  0   4   5   5   5   4   4
5:          5  0  0  0  5  1  0   5   4   4   4   4   4
6:          6  0  0  0  2  4  0   5   5   5   5   4   4
Run Code Online (Sandbox Code Playgroud)

如果您想使用仅包含数字的列名称:

df %>%
    mutate(across(`1`:`6`, ~ rowSums(across(NP1:NP6) == as.numeric(cur_column()))))

 Generacion 1 2 3 4 5 6 NP1 NP2 NP3 NP4 NP5 NP6
1          1 0 0 0 4 2 0   4   4   4   4   5   5
2          2 0 0 0 6 0 0   4   4   4   4   4   4
3          3 0 0 0 0 6 0   5   5   5   5   5   5
4          4 0 0 0 3 3 0   4   5   5   5   4   4
5          5 0 0 0 5 1 0   5   4   4   4   4   4
6          6 0 0 0 2 4 0   5   5   5   5   4   4
Run Code Online (Sandbox Code Playgroud)