我想创建一个robuust函数来在R中的data.table
中创建某些列的格式。我希望它尽可能健壮,因为我将在不同的数据集中使用它。数据不一致。数据示例如下:
此功能的目的是在data.table
中检查两列:group
和category
。它们原本是字符。我想对它们进行突变,使之:
组变量应该是一个因素,并且只能由级别A
,B
和U
组成。其他所有内容都应为U
。
类似地,变量category
应该是一个因素,并且仅由级别E
,CH
和S
组成。任何空单元格或NA
应该是E
。其他所有NA
。
我的原始数据包含成千上万的行,因此我正在寻找适合大数据的解决方案,最好是data.table
rm(iris)
iris
group <-rep(c("a", "b", "C", "x", "A", "b", " ", "b", NA , "c"), times = 15) # A,B,U
category <-rep(c("e", "E", "CH", "Ch", "ch", "S", " ", "b", NA , "c"), times = 15) # E, CH, S
iris <- cbind(iris, group, category)
iris <- iris[1:25,]
setDT(iris)
levels(iris$group) = list( U = "", F = "F", M = "M", U = "U")
levels(iris$category) = list( E = "", CH = "CH", E = "E", S = "S")
我已尝试通过以下方式进行此操作:1)指定允许的值,2)将所有值更改为大写字母,无论是否允许使用(理想情况下,可以使用apply
函数之一完成此操作)在data.table
中使用.SD
,但我还没有弄清楚它的工作原理)3)将allowed_group
或allowed category
中未指定的所有值替换为{{1 }}
NA
原始数据:
allowed_group <- c("U", "A", "B")
allowed_category <- c("E", "CH", "S")
iris$group <- toupper(iris$group)
iris$category <- toupper(iris$category)
iris[,!(group == allowed_group | category == allowed_category)] <- NA
所需的输出:
> iris
Sepal.Length Sepal.Width Petal.Length Petal.Width Species group category
1 5.1 3.5 1.4 0.2 setosa a e
2 4.9 3.0 1.4 0.2 setosa b E
3 4.7 3.2 1.3 0.2 setosa C CH
4 4.6 3.1 1.5 0.2 setosa x Ch
5 5.0 3.6 1.4 0.2 setosa A ch
6 5.4 3.9 1.7 0.4 setosa b S
7 4.6 3.4 1.4 0.3 setosa
8 5.0 3.4 1.5 0.2 setosa b b
9 4.4 2.9 1.4 0.2 setosa <NA> <NA>
10 4.9 3.1 1.5 0.1 setosa c c
11 5.4 3.7 1.5 0.2 setosa a e
12 4.8 3.4 1.6 0.2 setosa b E
13 4.8 3.0 1.4 0.1 setosa C CH
14 4.3 3.0 1.1 0.1 setosa x Ch
15 5.8 4.0 1.2 0.2 setosa A ch
16 5.7 4.4 1.5 0.4 setosa b S
17 5.4 3.9 1.3 0.4 setosa
18 5.1 3.5 1.4 0.3 setosa b b
19 5.7 3.8 1.7 0.3 setosa <NA> <NA>
20 5.1 3.8 1.5 0.3 setosa c c
21 5.4 3.4 1.7 0.2 setosa a e
22 5.1 3.7 1.5 0.4 setosa b E
23 4.6 3.6 1.0 0.2 setosa C CH
24 5.1 3.3 1.7 0.5 setosa x Ch
25 4.8 3.4 1.9 0.2 setosa A ch
答案 0 :(得分:0)
要进行条件替换,应使用第一维。使用data.table
操作:=
(通过引用更新),您无需重新分配值。我假设您要放入的NA位于group
和category
中。我认为使用factor
变量对可重现的示例没有帮助。但是,如果您的真实数据有影响因素,则可以在重新编码步骤之前将它们转换为字符。
iris
group <-rep(c("a", "b", "C", "x", "A", "b", " ", "b", NA , "c"), times = 15) # A,B,U
category <-rep(c("e", "E", "CH", "Ch", "ch", "S", " ", "b", NA , "c"), times = 15) # E, CH, S
iris <- cbind(iris, group, category)
iris <- iris[1:25,]
setDT(iris)
allowed_group <- c("U", "A", "B")
allowed_category <- c("E", "CH", "S")
iris[,c("group","category") := lapply(.SD, toupper),
.SDcols = c("group","category")]
现在有条件替换。我逐步使用变量,比过于复杂的第一个答案更容易处理:
iris[!(group %in% allowed_group), group := "U"]
iris[!(category %in% allowed_category), category := "E"]
产生:
iris
Sepal.Length Sepal.Width Petal.Length Petal.Width Species group category
1: 5.1 3.5 1.4 0.2 setosa A E
2: 4.9 3.0 1.4 0.2 setosa B E
3: 4.7 3.2 1.3 0.2 setosa U CH
4: 4.6 3.1 1.5 0.2 setosa U CH
5: 5.0 3.6 1.4 0.2 setosa A CH
6: 5.4 3.9 1.7 0.4 setosa B S
7: 4.6 3.4 1.4 0.3 setosa U E
8: 5.0 3.4 1.5 0.2 setosa B E
9: 4.4 2.9 1.4 0.2 setosa U E
10: 4.9 3.1 1.5 0.1 setosa U E
11: 5.4 3.7 1.5 0.2 setosa A E
12: 4.8 3.4 1.6 0.2 setosa B E
13: 4.8 3.0 1.4 0.1 setosa U CH
14: 4.3 3.0 1.1 0.1 setosa U CH
15: 5.8 4.0 1.2 0.2 setosa A CH
16: 5.7 4.4 1.5 0.4 setosa B S
17: 5.4 3.9 1.3 0.4 setosa U E
18: 5.1 3.5 1.4 0.3 setosa B E
19: 5.7 3.8 1.7 0.3 setosa U E
20: 5.1 3.8 1.5 0.3 setosa U E
21: 5.4 3.4 1.7 0.2 setosa A E
22: 5.1 3.7 1.5 0.4 setosa B E
23: 4.6 3.6 1.0 0.2 setosa U CH
24: 5.1 3.3 1.7 0.5 setosa U CH
25: 4.8 3.4 1.9 0.2 setosa A CH
Sepal.Length Sepal.Width Petal.Length Petal.Width Species group category