我看过R create a vector from conditional operation on matrix,并且使用类似的解决方案并不能达到我想要的效果(并且我不确定为什么)。
我的目标是在以下条件下评估df
:if df > 2, df -2, else 0
以df
:
a <- seq(1,5)
b <- seq(0,4)
df <- cbind(a,b) %>% as.data.frame()
df
很简单:
a b
1 0
2 1
3 2
4 3
5 4
df_final
在使用适当的功能后应如下所示:
a b
0 0
0 0
1 0
2 1
3 2
我在结果中应用了以下函数,但是我不确定为什么它不起作用(对解决方案的进一步解释将不胜枚举)
apply(df,2,function(df){
ifelse(any(df>2),df-2,0)
})
满足以下条件:
a b
-1 -2
谢谢您的社区!
答案 0 :(得分:2)
通过减去2创建'out'数据集,然后将基于逻辑条件的值替换为0
out <- df - 2
out[out < 0] <- 0
或一步一步
(df-2) * ((df - 2) > 0)
答案 1 :(得分:2)
让我们修复您的功能并了解为什么它不起作用:
apply(df, # apply to df
2, # to each *column* of df
function(df){ # this function. Call the function argument (each column) df
# (confusing because this is the same name as the data frame...)
ifelse( # Looking at each column...
any(df > 2), # if there are any values > 2
df - 2, # then df - 2
0 # otherwise 0
)
})
any()
返回单个值。 ifelse()
返回的形状与测试相同,因此通过使测试any(df > 2)
(单个值),ifelse()
也将返回单个值。
我们可以通过以下方法解决此问题:(a)将函数的名称更改为与输入不同的名称(出于可读性考虑),以及(b)取消any
:
apply(df, # apply to df
2, # to each *column* of df
function(x){ # this function. Call the function argument (each column) x
ifelse( # Looking at each column...
x > 2, # when x is > 2
df - 2, # make it x - 2
0 # otherwise 0
)
})
apply
用于处理矩阵。当给它一个数据帧时,它要做的第一件事就是将其转换为矩阵。如果要将结果作为数据帧,则需要将其转换回数据帧。
或者我们可以改用lapply
。 lapply
返回一个list
,通过使用df
将其分配到df[] <- lapply()
的列中,我们不需要进行转换。 (并且由于lapply
不进行矩阵转换,因此默认情况下它知道将函数应用于每一列。)
df[] <- lapply(df, function(x) ifelse(x > 2, x - 2, 0))
请注意,df <- cbind(a,b) %>% as.data.frame()
是写df <- data.frame(a, b)
的更复杂的方式
答案 2 :(得分:1)
使用申请
a <- seq(1,5)
b <- seq(0,4)
df <- cbind(a,b) %>% as.data.frame()
new_matrix <- apply(df, MARGIN=2,function(i)ifelse(i >2, i-2,0))
new_matrix
###if you want it to return a tibble/df
new_tibble <- apply(df, MARGIN=2,function(i)ifelse(i >2, i-2,0)) %>% as_tibble()