>我有以下数据框:
df <- as.data.frame(c(sort(rep(1:12, 4))))
colnames(df) <- c("A")
df
我希望创建一个新列('B'),将 1 分配给df$A == 1:3
的行,2 分配给df$A == 4:6
的行,将 3 分配给df$A == 7:9
的行等。结果应如下所示:
df <- as.data.frame(c(sort(rep(1:12, 4))))
colnames(df) <- c("A")
df$B <- c(sort(rep(1:4, 12)))
df
这里有一个问题:我不知道df$A
列中有多少个值等于 1、2、3 等。此外,df$A == 1
和df$A == 2
的行数不一定相等。
我知道我可以通过执行以下操作来解决此问题:
df$B <- ceiling(df$A/3)
还有什么其他方法可以解决这个问题?谢谢!
还有什么其他方法可以解决这个问题?谢谢!
您可以使用%/%
功能
df <- data.frame(A = 1:12)
str(df)
#R 'data.frame': 12 obs. of 1 variable:
#R $ A: int 1 2 3 4 5 6 7 8 9 10 ...
df$B <- 1L + (df$A - 1L) %/% 3L
str(df)
#R 'data.frame': 12 obs. of 2 variables:
#R $ A: int 1 2 3 4 5 6 7 8 9 10 ...
#R $ B: int 1 1 1 2 2 2 3 3 3 4 ...
确保使用整数,因为您可以在help("%/%")
中找到以下内容
x %/% y
可用于非整数y
,例如1 %/% 0.2
,但结果会受到表示误差的影响,因此可能取决于平台。由于IEC 60059表示0.2
是一个略大于0.2
的二进制分数,因此1 %/% 0.2
的答案应该是4
但大多数平台给出5
。
如果OP
打算将解决方案用作dplyr
链的一部分,而不是使用%%
,%/%
和tidyr::fill
可以是另一种选择,如下所示:
library(tidyverse)
df %>% arrange(A) %>%
mutate(B = ifelse(A%%3==0,A%/%3,NA_integer_)) %>%
fill(B, .direction = "up")
# A B
# 1 1 1
# 2 1 1
# 3 1 1
# 4 1 1
# 5 2 1
# 6 2 1
# 7 2 1
# 8 2 1
# 9 3 1
# 10 3 1
# 11 3 1
# 12 3 1
# 13 4 2
# 14 4 2
# 15 4 2
# 16 4 2
# 17 5 2
#
#...so on