rns*_*nso 34 r data.table
我有以下数据和代码来舍入此data.table的选定列:
> dput(mydf)
structure(list(vnum1 = c(0.590165705411504, -1.39939534199836,
0.720226053660755, -0.253198380120377, -0.783366825121657), vnum2 = c(0.706508400384337,
0.526770398486406, 0.863136084517464, 0.838245498016477, 0.556775856064633
), vch1 = structure(c(2L, 4L, 1L, 3L, 3L), .Label = c("A", "B",
"C", "E"), class = "factor")), .Names = c("vnum1", "vnum2", "vch1"
), row.names = c(NA, -5L), class = c("data.table", "data.frame"
))
> mydf[,round(.SD,1),]
Error in Math.data.frame(list(vnum1 = c(0.590165705411504, -1.39939534199836, :
non-numeric variable in data frame: vch1
> cbind(mydf[,3,with=F], mydf[,1:2,with=F][,round(.SD,1),])
vch1 vnum1 vnum2
1: B 0.6 0.7
2: E -1.4 0.5
3: A 0.7 0.9
4: C -0.3 0.8
5: C -0.8 0.6
Run Code Online (Sandbox Code Playgroud)
有更好的方法(更短的代码)?谢谢你的帮助.
Ste*_*pré 48
运用 dplyr
如果要一次舍入多个列:
mydf %>% mutate_at(vars(vnum1, vnum2), funs(round(., 1)))
Run Code Online (Sandbox Code Playgroud)
或者,如果要更改除"vch1"之外的所有列:
mydf %>% mutate_at(vars(-vch1), funs(round(., 1)))
Run Code Online (Sandbox Code Playgroud)
或者,如果要更改以"vnum"开头的所有列:
mydf %>% mutate_at(vars(starts_with("vnum")), funs(round(., 1)))
Run Code Online (Sandbox Code Playgroud)
或者,如果您只想更改数字列:
mydf %>% mutate_if(is.numeric, ~round(., 1))
Run Code Online (Sandbox Code Playgroud)
你得到:
vnum1 vnum2 vch1
1 0.6 0.7 B
2 -1.4 0.5 E
3 0.7 0.9 A
4 -0.3 0.8 C
5 -0.8 0.6 C
Run Code Online (Sandbox Code Playgroud)
the*_*ail 28
如果你不介意覆盖原文mydf:
cols <- names(mydf)[1:2]
mydf[,(cols) := round(.SD,1), .SDcols=cols]
mydf
# vnum1 vnum2 vch1
#1: 0.6 0.7 B
#2: -1.4 0.5 E
#3: 0.7 0.9 A
#4: -0.3 0.8 C
#5: -0.8 0.6 C
Run Code Online (Sandbox Code Playgroud)
Art*_*Yip 25
鉴于dplyr::mutate_each已弃用,mutate_if只有在数字为圆时才使用舍入列的额外好处
mydf %>% mutate_if(is.numeric, round, 1)
需要(data.table)
简短明了的解决方案:
mydf[, lapply(.SD, round, 1), vch1]
# vch1 vnum1 vnum2
#1: B 0.6 0.7
#2: E -1.4 0.5
#3: A 0.7 0.9
#4: C -0.3 0.8
#5: C -0.8 0.6
Run Code Online (Sandbox Code Playgroud)
相同,但有描述性的细节:
mydf[, lapply(.SD, round, digits = 1), by = vch1]
Run Code Online (Sandbox Code Playgroud)
如果我有很多列,请说:(vnum1,vnum2,vch1,vch2,vbin1,vbin2,vbin3),我想只舍入vnum1和vnum2?
在这种情况下,您可以使用:=运算符和.SDcols =参数来指定要舍入的列:
mydf[, 1:2 := lapply(.SD, round, digits = 1), by = vch1]
Run Code Online (Sandbox Code Playgroud)
如果您需要舍入某些列并从输出中排除其他列,您可以使用just .SDcols =参数同时执行这两个操作:
mydf[, lapply(.SD, round, digits = 1), by = vch1, .SDcols = "vnum1"]
Run Code Online (Sandbox Code Playgroud)
.SDcols =可以提供列名称或它的编号,
作为单个列的名称.SDcols = "vnum1"或数字.SDcols = 1
作为多列的名称.SDcols = c("vnum2", "vnum1")或数字.SDcols = c(2, 1)
作为列按名称.SDcols = vnum1:vnum2或数字.SDcols = 1:2
截至dplyr0.8.0,funs()是软弃用。这意味着list(name = ~f(.))应该代替funs(name = f(.)):
mydf %>%
mutate_at(vars(vnum1, vnum2), list(~ round(., 1)))
vnum1 vnum2 vch1
1 0.6 0.7 B
2 -1.4 0.5 E
3 0.7 0.9 A
4 -0.3 0.8 C
5 -0.8 0.6 C
Run Code Online (Sandbox Code Playgroud)
但是,在这种情况下,不需要使用任何功能(因为只有一个功能),@ Arthur Yip的方法可以应用于所有方案。
通过其名称显式选择列:
mydf %>%
mutate_at(vars(vnum1, vnum2), round, 1)
Run Code Online (Sandbox Code Playgroud)
或选择以开头的列vnum:
mydf %>%
mutate_at(vars(starts_with("vnum")), round, 1)
Run Code Online (Sandbox Code Playgroud)
或选择包含vnum以下内容的列:
mydf %>%
mutate_at(vars(contains("vnum")), round, 1)
Run Code Online (Sandbox Code Playgroud)
或选择匹配的列vnum:
mydf %>%
mutate_at(vars(matches("vnum")), round, 1)
Run Code Online (Sandbox Code Playgroud)
或按名称明确排除列:
mydf %>%
mutate_at(vars(-vch1), round, 1)
Run Code Online (Sandbox Code Playgroud)
或排除匹配的列vch:
mydf %>%
mutate_at(vars(-matches("vch")), round, 1)
Run Code Online (Sandbox Code Playgroud)
或选择前两列:
mydf %>%
mutate_at(1:2, round, 1)
Run Code Online (Sandbox Code Playgroud)
或排除第三列:
mydf %>%
mutate_at(-3, round, 1)
Run Code Online (Sandbox Code Playgroud)