按名称减去数据框的列
Subtracting columns of data frame by name
假设我有如下数据框:
df <- as.data.frame(matrix(seq(1,20,1),nrow=4), byrow=TRUE)
colnames(df) <- c("X1","X2","X3","X4","X5")
rownames(df) <- as.Date(c("2020-01-02","2020-01-03","2020-01-04","2020-01-05"))
df
X1 X2 X3 X4 X5
2020-01-02 1 2 3 4 5
2020-01-03 6 7 8 9 10
2020-01-04 11 12 13 14 15
2020-01-05 16 17 18 19 20
我想从第一列中减去所有列 X1
并将其存储在同一列中。我试过
for(i in colnames(df)){
df[i] <- lapply(df[i], function(x) x-df["X1"])
}
但它只适用于第一列。我怎样才能 运行 它用于所有列?
试试这个 base R
没有循环的解决方案。请记住列的位置:
#Data
df <- as.data.frame(matrix(seq(1,20,1),nrow=4), byrow=TRUE)
colnames(df) <- c("X1","X2","X3","X4","X5")
rownames(df) <- as.Date(c("2020-01-02","2020-01-03","2020-01-04","2020-01-05"))
#Set columns for difference
df[,2:5] <- df[,2:5]-df[,1]
输出:
X1 X2 X3 X4 X5
2020-01-02 1 4 8 12 16
2020-01-03 2 4 8 12 16
2020-01-04 3 4 8 12 16
2020-01-05 4 4 8 12 16
或者更复杂的方法是:
#Create index
#Var to substract
i1 <- which(names(df)=='X1')
#Vars to be substracted with X1
i2 <- which(names(df)!='X1')
#Compute
df[,i2]<-df[,i2]-df[,i1]
输出:
X1 X2 X3 X4 X5
2020-01-02 1 4 8 12 16
2020-01-03 2 4 8 12 16
2020-01-04 3 4 8 12 16
2020-01-05 4 4 8 12 16
如果你想坚持 lapply
你可以这样做:
df[] <- lapply(df, `-`, df$X1)
df
# X1 X2 X3 X4 X5
# 2020-01-02 0 4 8 12 16
# 2020-01-03 0 4 8 12 16
# 2020-01-04 0 4 8 12 16
# 2020-01-05 0 4 8 12 16
这是 grep
的一种方式:
i_col <- grep("X1", names(df))
df[] <- df - df[, i_col]
df
# X1 X2 X3 X4 X5
#2020-01-02 0 4 8 12 16
#2020-01-03 0 4 8 12 16
#2020-01-04 0 4 8 12 16
#2020-01-05 0 4 8 12 16
另一个 grep/sweep
。事实上,-
是sweep
的默认函数。
sweep(df, 1, df[[i_col]], check.margin = FALSE)
# X1 X2 X3 X4 X5
#2020-01-02 0 4 8 12 16
#2020-01-03 0 4 8 12 16
#2020-01-04 0 4 8 12 16
#2020-01-05 0 4 8 12 16
假设我有如下数据框:
df <- as.data.frame(matrix(seq(1,20,1),nrow=4), byrow=TRUE)
colnames(df) <- c("X1","X2","X3","X4","X5")
rownames(df) <- as.Date(c("2020-01-02","2020-01-03","2020-01-04","2020-01-05"))
df
X1 X2 X3 X4 X5
2020-01-02 1 2 3 4 5
2020-01-03 6 7 8 9 10
2020-01-04 11 12 13 14 15
2020-01-05 16 17 18 19 20
我想从第一列中减去所有列 X1
并将其存储在同一列中。我试过
for(i in colnames(df)){
df[i] <- lapply(df[i], function(x) x-df["X1"])
}
但它只适用于第一列。我怎样才能 运行 它用于所有列?
试试这个 base R
没有循环的解决方案。请记住列的位置:
#Data
df <- as.data.frame(matrix(seq(1,20,1),nrow=4), byrow=TRUE)
colnames(df) <- c("X1","X2","X3","X4","X5")
rownames(df) <- as.Date(c("2020-01-02","2020-01-03","2020-01-04","2020-01-05"))
#Set columns for difference
df[,2:5] <- df[,2:5]-df[,1]
输出:
X1 X2 X3 X4 X5
2020-01-02 1 4 8 12 16
2020-01-03 2 4 8 12 16
2020-01-04 3 4 8 12 16
2020-01-05 4 4 8 12 16
或者更复杂的方法是:
#Create index
#Var to substract
i1 <- which(names(df)=='X1')
#Vars to be substracted with X1
i2 <- which(names(df)!='X1')
#Compute
df[,i2]<-df[,i2]-df[,i1]
输出:
X1 X2 X3 X4 X5
2020-01-02 1 4 8 12 16
2020-01-03 2 4 8 12 16
2020-01-04 3 4 8 12 16
2020-01-05 4 4 8 12 16
如果你想坚持 lapply
你可以这样做:
df[] <- lapply(df, `-`, df$X1)
df
# X1 X2 X3 X4 X5
# 2020-01-02 0 4 8 12 16
# 2020-01-03 0 4 8 12 16
# 2020-01-04 0 4 8 12 16
# 2020-01-05 0 4 8 12 16
这是 grep
的一种方式:
i_col <- grep("X1", names(df))
df[] <- df - df[, i_col]
df
# X1 X2 X3 X4 X5
#2020-01-02 0 4 8 12 16
#2020-01-03 0 4 8 12 16
#2020-01-04 0 4 8 12 16
#2020-01-05 0 4 8 12 16
另一个 grep/sweep
。事实上,-
是sweep
的默认函数。
sweep(df, 1, df[[i_col]], check.margin = FALSE)
# X1 X2 X3 X4 X5
#2020-01-02 0 4 8 12 16
#2020-01-03 0 4 8 12 16
#2020-01-04 0 4 8 12 16
#2020-01-05 0 4 8 12 16