我有一个包含许多列的数据框。列的类型不同:有些是数字,有些是字符等。这里有一个小例子,我们只有2个类型的3个变量:
# Generate data
dat <- data.frame(x = c("1","2","3"),
y = c(1.0,2.5,3.3),
z = c(1,2,3),
stringsAsFactors = FALSE)
我想用空格替换值3,但仅限于字符列。这是我目前的代码:
out <- as.data.frame(lapply(dat, function(x) {
ifelse(is.character(x),
gsub("3", " ", x),
x)}),
stringsAsFactors = FALSE)
问题是ifelse()函数忽略了y和z是数字,并且它似乎也将数字变量强制转换为字符。
想法是将字符列gsub()拉出来,然后将它们绑定回原始数据框。但是,这会改变列的顺序。任何解决方案的关键是我不需要按名称指定变量,只需要按类型指定。
答案 0 :(得分:2)
我尝试了您的代码,对我而言似乎ifelse
无法正常工作,但将if
广告else
分开了。以下是有效的代码:
# Generate data
dat <- data.frame(x = c("1","2","3"),
y = c(1.0,2.5,3.3),
z = c(1,2,3),
stringsAsFactors = FALSE)
> lapply(dat, function(x) { if(is.character(x)) gsub("3", " ", x) else x })
$x
[1] "1" "2" " "
$y
[1] 1.0 2.5 3.3
$z
[1] 1 2 3
> as.data.frame(lapply(dat, function(x) { if(is.character(x)) gsub("3", " ", x) else x }))
x y z
1 1 1.0 1
2 2 2.5 2
3 3.3 3
答案 1 :(得分:2)
归结为?ifelse
ifelse
返回与<{1}}具有相同形状的值 ...
test
的长度为1,因此返回的值为长度1.您可以按照建议使用is.character
,而不是@Heikki建议的。
答案 2 :(得分:2)
也可以使用dplyr轻松地做到这一点:
# Load package
library(dplyr)
# Create data
dat <- data.frame(x = c("1","2","3"),
y = c(1.0,2.5,3.3),
z = c(1,2,3),
stringsAsFactors = FALSE)
# Replace 3's with spaces for character columns
dat <- dat %>% mutate_if(is.character, function(x) gsub(pattern = "3", " ", x))
答案 3 :(得分:1)
与@ user3614648解决方案类似:
library(dplyr)
dat %>%
mutate_if(is.character, funs(ifelse(. == "3", " ", .)))
x y z
1 1 1.0 1
2 2 2.5 2
3 3.3 3