R:仅对字符列应用函数而不使用类型强制

时间:2017-10-15 07:22:04

标签: r

我有一个包含许多列的数据框。列的类型不同:有些是数字,有些是字符等。这里有一个小例子,我们只有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()拉出来,然后将它们绑定回原始数据框。但是,这会改变列的顺序。任何解决方案的关键是我不需要按名称指定变量,只需要按类型指定。

4 个答案:

答案 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