我有一个像这样的数据框
Letter Number1 Number2 Number3 Type
A 4 5 3 10
B 10 22 24 20
C 50 24 100 30
D 60 32 12 40
我想使用mutate_each将number1,number2和number3除以2,而不对Letter和type做任何事情。 有一个轻松的日子吗?
这就是我希望最终的DF看起来像
Letter Number1 Number2 Number3 Type
A 2 2.5 1.5 10
B 5 11 12 20
C 25 12 50 30
D 30 16 6 40
谢谢!
答案 0 :(得分:5)
我们可以使用starts_with
或matches
选择“数字”列,并将这些列除以2.
library(dplyr)
mutate_each(df1, funs(./2), starts_with('Number'))
# Letter Number1 Number2 Number3 Type
#1 A 2 2.5 1.5 10
#2 B 5 11.0 12.0 20
#3 C 25 12.0 50.0 30
#4 D 30 16.0 6.0 40
正如@ Cotton.Rockwood在评论中建议的那样,在较新版本的dplyr
(0.7.6
)中,我们可以使用mutate_at
(用于更改列的子集)或{{ 1}}(改变所有列)
mutate_all
或者使用df1 %>%
mutate_at(vars(starts_with("Number")), funs(./2))
,我们将'data.frame'转换为'data.table'(data.table
),获取以'Number'('nm1')开头的列名,assign具有新值的'nm1'即。除以'2'后。
setDT(df1)
对于多列,使用library(data.table)#v1.9.4+
setDT(df1)
nm1 <- grep('^Number', names(df1), value=TRUE)
df1[, (nm1):= lapply(.SD, `/`, 2), .SDcols=nm1]
的更有效方法将使用data.table
。
set
for(j in nm1){
set(df1, i=NULL, j=j, value=df1[[j]]/2)
}
答案 1 :(得分:4)
以下基础R
解决方案:
indx <- grepl("Number", names(df))
df[indx] <- df[indx]/2L
#>df
# Letter Number1 Number2 Number3 Type
#1 A 2 2.5 1.5 10
#2 B 5 11.0 12.0 20
#3 C 25 12.0 50.0 30
#4 D 30 16.0 6.0 40
答案 2 :(得分:1)
library(dplyr)
创建测试数据框
letter <- c("A", "B", "C", "D")
n1 <- c(4, 10, 50, 60)
n2 <- c(5, 22, 24, 32)
n3 <- c(3, 24, 100, 12)
type <- c(10, 20, 30, 40)
df <- data.frame(letter, n1, n2, n3, type)
数据框df:
# letter n1 n2 n3 type
# 1 A 4 5 3 10
# 2 B 10 22 24 20
# 3 C 50 24 100 30
# 4 D 60 32 12 40
制作自己的功能
mydivide <- function(x){x/2}
使用funs()告诉mutate使用什么函数。
使用' - '告诉mutate不要改变列'letter'和'type'
df <- mutate_each(df, funs(mydivide), -letter, -type)
最终结果:
# letter n1 n2 n3 type
# 1 A 2 2.5 1.5 10
# 2 B 5 11.0 12.0 20
# 3 C 25 12.0 50.0 30
# 4 D 30 16.0 6.0 40