I have a dataframe with data organised like this:
data <- structure(list(group = c("a", "a", "b", "b"), yr1 = c(1927L, 1953L, 1957L, 1961L), yr2 = c(1934L, 1955L, 1958L, 1965L), val = c("1", "1", "1", "NA"), col2 = c("x", " -x", " ", " x ")), .Names = c("group", "yr1", "yr2", "val", "col2"), class = "data.frame", row.names = c(NA, -4L))
group yr1 yr2 val col2
1 a 1927 1934 1 x
2 a 1953 1955 1 -x
3 b 1957 1958 1
4 b 1961 1965 NA x
What I'd like to do is to check column val
and if there is NA replace it with the value 1 if a certain string in column col2
is true (in this case x).
There might be other strings for the condition which I could maybe sumarise.
values <- c("x", "test", "nts", "kfc")
The result for the sample data I am aiming for looks like this:
group yr1 yr2 val col2
1 a 1927 1934 1 x
2 a 1953 1955 1 -x
3 b 1957 1958 1
4 b 1961 1965 1 x
I have tried to do it with subsetting like this but failed.
data[data$col2 == "x", ][, "val"] <- "1"
Does anyone have an idea how to solve this?
In your case NA
is a character 'NA'
Also, there seems to be leading/lagging spaces for the col2
.
data$col2
#[1] "x" " -x" " " " x "
So,
data$col2=='x'
#[1] TRUE FALSE FALSE FALSE
and because NA
is character string
is.na(data$val)
#[1] FALSE FALSE FALSE FALSE
Because of the above mentioned problems, I would use
data[with(data, grepl('x', col2) & val=='NA'),'val'] <- 1
In cases with leading/lagging spaces, you could remove those for the columns of interest (suppose, group
and col2
)
library(stringr)
data[c('group', 'col2')] <- lapply(data[c('group', 'col2')], str_trim)
Or
data[c('group', 'col2')] <- lapply(data[c('group', 'col2')],
function(x) gsub('^ +| +$', '', x))
and if you change the 'NA'
to NA
data$val[data$val=='NA'] <- NA
then you could use @Neal Fultz's solution as well
您可以使用&
组合条件。
data[data$col2 == "x" & is.na(data$val), "val"] <- 1
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.