如何在不丢失其他列的情况下将 sapply 循环的输出分配给数据框中的原始列
How to assign the output of a sapply loop to the original columns in a data frame without losing other columns
我是一个包含不同列的数据框,其中包含来自不同评估员的字符串答案,他们在答案中使用随机的大写或小写字母。我想将所有内容都转换为小写。我的代码如下:
# Creating a reproducible data frame similar to what I am working with
dfrm <- data.frame(a = sample(names(islands))[1:20],
b = sample(unname(islands))[1:20],
c = sample(names(islands))[1:20],
d = sample(unname(islands))[1:20],
e = sample(names(islands))[1:20],
f = sample(unname(islands))[1:20],
g = sample(names(islands))[1:20],
h = sample(unname(islands))[1:20])
# This is how I did it originally by writing everything explicitly:
dfrm1 <- dfrm
dfrm1$a <- tolower(dfrm1$a)
dfrm1$c <- tolower(dfrm1$c)
dfrm1$e <- tolower(dfrm1$e)
dfrm1$g <- tolower(dfrm1$g)
head(dfrm1) #Works as intended
问题是随着评估员人数的增加,我一直在复制粘贴错误。我试图通过为 tolower
编写一个函数来简化我的代码,并使用 sapply
循环它,但最终的数据框看起来不像我想要的:
# function and sapply:
dfrm2 <- dfrm
my_list <- c("a", "c", "e", "g")
my_low <- function(x){dfrm2[,x] <- tolower(dfrm2[,x])}
sapply(my_list, my_low) #Didn't work
# Alternative approach:
dfrm2 <- as.data.frame(sapply(my_list, my_low))
head(dfrm2) #Lost the numbers
我错过了什么?
我知道这一定是一个我没有理解的非常基本的概念。有 , and 。感谢任何帮助,谢谢!
对于您的第一次尝试,如果您希望对数据框 dfrm2
的赋值保持不变,请使用 <<-
赋值运算符:
my_low <- function(x){ dfrm2[,x] <<- tolower(dfrm2[,x]) }
sapply(my_list, my_low)
也许您想创建一个逻辑向量,其中 select 要更改的列和 运行 仅对这些列应用函数。
# only choose non-numeric columns
changeCols <- !sapply(dfrm, is.numeric)
# change values of selected columns to lower case
dfrm[changeCols] <- lapply(dfrm[changeCols], tolower)
如果您有其他类型的列,比如逻辑列,您还可以更明确地说明要更改的列类型。例如,要 select 只有因子和字符列,请使用。
changeCols <- sapply(dfrm, function(x) is.factor(x) | is.character(x))
我是一个包含不同列的数据框,其中包含来自不同评估员的字符串答案,他们在答案中使用随机的大写或小写字母。我想将所有内容都转换为小写。我的代码如下:
# Creating a reproducible data frame similar to what I am working with
dfrm <- data.frame(a = sample(names(islands))[1:20],
b = sample(unname(islands))[1:20],
c = sample(names(islands))[1:20],
d = sample(unname(islands))[1:20],
e = sample(names(islands))[1:20],
f = sample(unname(islands))[1:20],
g = sample(names(islands))[1:20],
h = sample(unname(islands))[1:20])
# This is how I did it originally by writing everything explicitly:
dfrm1 <- dfrm
dfrm1$a <- tolower(dfrm1$a)
dfrm1$c <- tolower(dfrm1$c)
dfrm1$e <- tolower(dfrm1$e)
dfrm1$g <- tolower(dfrm1$g)
head(dfrm1) #Works as intended
问题是随着评估员人数的增加,我一直在复制粘贴错误。我试图通过为 tolower
编写一个函数来简化我的代码,并使用 sapply
循环它,但最终的数据框看起来不像我想要的:
# function and sapply:
dfrm2 <- dfrm
my_list <- c("a", "c", "e", "g")
my_low <- function(x){dfrm2[,x] <- tolower(dfrm2[,x])}
sapply(my_list, my_low) #Didn't work
# Alternative approach:
dfrm2 <- as.data.frame(sapply(my_list, my_low))
head(dfrm2) #Lost the numbers
我错过了什么?
我知道这一定是一个我没有理解的非常基本的概念。有
对于您的第一次尝试,如果您希望对数据框 dfrm2
的赋值保持不变,请使用 <<-
赋值运算符:
my_low <- function(x){ dfrm2[,x] <<- tolower(dfrm2[,x]) }
sapply(my_list, my_low)
也许您想创建一个逻辑向量,其中 select 要更改的列和 运行 仅对这些列应用函数。
# only choose non-numeric columns
changeCols <- !sapply(dfrm, is.numeric)
# change values of selected columns to lower case
dfrm[changeCols] <- lapply(dfrm[changeCols], tolower)
如果您有其他类型的列,比如逻辑列,您还可以更明确地说明要更改的列类型。例如,要 select 只有因子和字符列,请使用。
changeCols <- sapply(dfrm, function(x) is.factor(x) | is.character(x))